mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Document Devtools' property defaults directly in reference docs
Closes gh-29406
This commit is contained in:
parent
bbdef2b026
commit
cced7edd9c
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2022 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.springframework.boot.build.devtools;
|
||||||
|
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import org.gradle.api.DefaultTask;
|
||||||
|
import org.gradle.api.artifacts.Configuration;
|
||||||
|
import org.gradle.api.file.FileCollection;
|
||||||
|
import org.gradle.api.file.RegularFileProperty;
|
||||||
|
import org.gradle.api.tasks.InputFiles;
|
||||||
|
import org.gradle.api.tasks.OutputFile;
|
||||||
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task for documenting Devtools' property defaults.
|
||||||
|
*
|
||||||
|
* @author Andy Wilkinson
|
||||||
|
*/
|
||||||
|
public class DocumentDevtoolsPropertyDefaults extends DefaultTask {
|
||||||
|
|
||||||
|
private Configuration devtools;
|
||||||
|
|
||||||
|
private final RegularFileProperty outputFile;
|
||||||
|
|
||||||
|
public DocumentDevtoolsPropertyDefaults() {
|
||||||
|
this.devtools = getProject().getConfigurations().create("devtools");
|
||||||
|
this.outputFile = getProject().getObjects().fileProperty();
|
||||||
|
this.outputFile.convention(getProject().getLayout().getBuildDirectory()
|
||||||
|
.file("docs/generated/using/devtools-property-defaults.adoc"));
|
||||||
|
Map<String, String> dependency = new HashMap<>();
|
||||||
|
dependency.put("path", ":spring-boot-project:spring-boot-devtools");
|
||||||
|
dependency.put("configuration", "propertyDefaults");
|
||||||
|
this.devtools.getDependencies().add(getProject().getDependencies().project(dependency));
|
||||||
|
}
|
||||||
|
|
||||||
|
@InputFiles
|
||||||
|
public FileCollection getDevtools() {
|
||||||
|
return this.devtools;
|
||||||
|
}
|
||||||
|
|
||||||
|
@OutputFile
|
||||||
|
public RegularFileProperty getOutputFile() {
|
||||||
|
return this.outputFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
void documentPropertyDefaults() throws IOException {
|
||||||
|
Map<String, String> properties = loadProperties();
|
||||||
|
documentProperties(properties);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> loadProperties() throws IOException, FileNotFoundException {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
Map<String, String> sortedProperties = new TreeMap<>();
|
||||||
|
try (FileInputStream stream = new FileInputStream(this.devtools.getSingleFile())) {
|
||||||
|
properties.load(stream);
|
||||||
|
for (String name : properties.stringPropertyNames()) {
|
||||||
|
sortedProperties.put(name, properties.getProperty(name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sortedProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void documentProperties(Map<String, String> properties) throws IOException {
|
||||||
|
try (PrintWriter writer = new PrintWriter(new FileWriter(this.outputFile.getAsFile().get()))) {
|
||||||
|
writer.println("[cols=\"3,1\"]");
|
||||||
|
writer.println("|===");
|
||||||
|
writer.println("| Name | Default Value");
|
||||||
|
properties.forEach((name, value) -> {
|
||||||
|
writer.println();
|
||||||
|
writer.printf("| `%s`%n", name);
|
||||||
|
writer.printf("| `%s`%n", value);
|
||||||
|
});
|
||||||
|
writer.println("|===");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -13,6 +13,13 @@ configurations {
|
|||||||
intTestDependencies {
|
intTestDependencies {
|
||||||
extendsFrom dependencyManagement
|
extendsFrom dependencyManagement
|
||||||
}
|
}
|
||||||
|
propertyDefaults
|
||||||
|
}
|
||||||
|
|
||||||
|
artifacts {
|
||||||
|
propertyDefaults(file("build/resources/main/org/springframework/boot/devtools/env/devtools-property-defaults.properties")) {
|
||||||
|
builtBy(processResources)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -16,9 +16,11 @@
|
|||||||
|
|
||||||
package org.springframework.boot.devtools.env;
|
package org.springframework.boot.devtools.env;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
|
|
||||||
@ -62,23 +64,19 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro
|
|||||||
private static final Map<String, Object> PROPERTIES;
|
private static final Map<String, Object> PROPERTIES;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Map<String, Object> properties = new HashMap<>();
|
Properties properties = new Properties();
|
||||||
properties.put("spring.thymeleaf.cache", "false");
|
try (InputStream stream = DevToolsPropertyDefaultsPostProcessor.class
|
||||||
properties.put("spring.freemarker.cache", "false");
|
.getResourceAsStream("devtools-property-defaults.properties")) {
|
||||||
properties.put("spring.groovy.template.cache", "false");
|
properties.load(stream);
|
||||||
properties.put("spring.mustache.cache", "false");
|
}
|
||||||
properties.put("server.servlet.session.persistent", "true");
|
catch (IOException ex) {
|
||||||
properties.put("spring.h2.console.enabled", "true");
|
throw new RuntimeException("Failed to load devtools-property-defaults.properties", ex);
|
||||||
properties.put("spring.web.resources.cache.period", "0");
|
}
|
||||||
properties.put("spring.web.resources.chain.cache", "false");
|
Map<String, Object> map = new HashMap<>();
|
||||||
properties.put("spring.template.provider.cache", "false");
|
for (String name : properties.stringPropertyNames()) {
|
||||||
properties.put("spring.mvc.log-resolved-exception", "true");
|
map.put(name, properties.getProperty(name));
|
||||||
properties.put("server.error.include-binding-errors", "ALWAYS");
|
}
|
||||||
properties.put("server.error.include-message", "ALWAYS");
|
PROPERTIES = map;
|
||||||
properties.put("server.error.include-stacktrace", "ALWAYS");
|
|
||||||
properties.put("server.servlet.jsp.init-parameters.development", "true");
|
|
||||||
properties.put("spring.reactor.debug", "true");
|
|
||||||
PROPERTIES = Collections.unmodifiableMap(properties);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
server.error.include-binding-errors=always
|
||||||
|
server.error.include-message=always
|
||||||
|
server.error.include-stacktrace=always
|
||||||
|
server.servlet.jsp.init-parameters.development=true
|
||||||
|
server.servlet.session.persistent=true
|
||||||
|
spring.freemarker.cache=false
|
||||||
|
spring.groovy.template.cache=false
|
||||||
|
spring.h2.console.enabled=true
|
||||||
|
spring.mustache.cache=false
|
||||||
|
spring.mvc.log-resolved-exception=true
|
||||||
|
spring.reactor.debug=true
|
||||||
|
spring.template.provider.cache=false
|
||||||
|
spring.thymeleaf.cache=false
|
||||||
|
spring.web.resources.cache.period=0
|
||||||
|
spring.web.resources.chain.cache=false
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2020 the original author or authors.
|
* Copyright 2012-2022 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -18,6 +18,7 @@ package org.springframework.boot.devtools.env;
|
|||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
@ -107,9 +108,11 @@ class DevToolPropertiesIntegrationTests {
|
|||||||
this.context = getContext(application::run);
|
this.context = getContext(application::run);
|
||||||
ConfigurableEnvironment environment = this.context.getEnvironment();
|
ConfigurableEnvironment environment = this.context.getEnvironment();
|
||||||
String includeStackTrace = environment.getProperty("server.error.include-stacktrace");
|
String includeStackTrace = environment.getProperty("server.error.include-stacktrace");
|
||||||
assertThat(includeStackTrace).isEqualTo(ErrorProperties.IncludeAttribute.ALWAYS.toString());
|
assertThat(includeStackTrace)
|
||||||
|
.isEqualTo(ErrorProperties.IncludeAttribute.ALWAYS.toString().toLowerCase(Locale.ENGLISH));
|
||||||
String includeMessage = environment.getProperty("server.error.include-message");
|
String includeMessage = environment.getProperty("server.error.include-message");
|
||||||
assertThat(includeMessage).isEqualTo(ErrorProperties.IncludeAttribute.ALWAYS.toString());
|
assertThat(includeMessage)
|
||||||
|
.isEqualTo(ErrorProperties.IncludeAttribute.ALWAYS.toString().toLowerCase(Locale.ENGLISH));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ConfigurableApplicationContext getContext(Supplier<ConfigurableApplicationContext> supplier)
|
protected ConfigurableApplicationContext getContext(Supplier<ConfigurableApplicationContext> supplier)
|
||||||
|
@ -243,6 +243,8 @@ task documentConfigurationProperties(type: org.springframework.boot.build.contex
|
|||||||
outputDir = file("${buildDir}/docs/generated/")
|
outputDir = file("${buildDir}/docs/generated/")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task documentDevtoolsPropertyDefaults(type: org.springframework.boot.build.devtools.DocumentDevtoolsPropertyDefaults) {}
|
||||||
|
|
||||||
tasks.withType(org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask) {
|
tasks.withType(org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask) {
|
||||||
dependsOn dependencyVersions
|
dependsOn dependencyVersions
|
||||||
asciidoctorj {
|
asciidoctorj {
|
||||||
@ -296,6 +298,7 @@ syncDocumentationSourceForAsciidoctor {
|
|||||||
dependsOn documentDependencyVersions
|
dependsOn documentDependencyVersions
|
||||||
dependsOn documentVersionProperties
|
dependsOn documentVersionProperties
|
||||||
dependsOn documentConfigurationProperties
|
dependsOn documentConfigurationProperties
|
||||||
|
dependsOn documentDevtoolsPropertyDefaults
|
||||||
from("${buildDir}/docs/generated") {
|
from("${buildDir}/docs/generated") {
|
||||||
into "asciidoc"
|
into "asciidoc"
|
||||||
}
|
}
|
||||||
|
@ -67,13 +67,15 @@ Cache options are usually configured by settings in your `application.properties
|
|||||||
For example, Thymeleaf offers the configprop:spring.thymeleaf.cache[] property.
|
For example, Thymeleaf offers the configprop:spring.thymeleaf.cache[] property.
|
||||||
Rather than needing to set these properties manually, the `spring-boot-devtools` module automatically applies sensible development-time configuration.
|
Rather than needing to set these properties manually, the `spring-boot-devtools` module automatically applies sensible development-time configuration.
|
||||||
|
|
||||||
Because you need more information about web requests while developing Spring MVC and Spring WebFlux applications, developer tools suggests you to enable `DEBUG` logging for the `web` logging group.
|
The following table lists all the properties that are applied:
|
||||||
This will give you information about the incoming request, which handler is processing it, the response outcome, etc.
|
|
||||||
If you wish to log all request details (including potentially sensitive information), you can turn on the configprop:spring.mvc.log-request-details[] or configprop:spring.codec.log-request-details[] configuration properties.
|
include::devtools-property-defaults.adoc[]
|
||||||
|
|
||||||
NOTE: If you don't want property defaults to be applied you can set configprop:spring.devtools.add-properties[] to `false` in your `application.properties`.
|
NOTE: If you don't want property defaults to be applied you can set configprop:spring.devtools.add-properties[] to `false` in your `application.properties`.
|
||||||
|
|
||||||
TIP: For a complete list of the properties that are applied by the devtools, see {spring-boot-devtools-module-code}/env/DevToolsPropertyDefaultsPostProcessor.java[DevToolsPropertyDefaultsPostProcessor].
|
Because you need more information about web requests while developing Spring MVC and Spring WebFlux applications, developer tools suggests you to enable `DEBUG` logging for the `web` logging group.
|
||||||
|
This will give you information about the incoming request, which handler is processing it, the response outcome, etc.
|
||||||
|
If you wish to log all request details (including potentially sensitive information), you can turn on the configprop:spring.mvc.log-request-details[] or configprop:spring.codec.log-request-details[] configuration properties.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user