Remove Servlet-specific static locations
This commit removes the Servlet root context from the default values for the `spring.resources.static-locations` configuration property. Servlet and non-Servlet applications are sharing this property. The Servlet root context is automatically configured as a resource location for Spring MVC based applications. Closes gh-9240
This commit is contained in:
parent
eb4a9d87fd
commit
9dd3fb70e2
|
|
@ -16,15 +16,7 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.web;
|
package org.springframework.boot.autoconfigure.web;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.context.ResourceLoaderAware;
|
|
||||||
import org.springframework.core.io.ClassPathResource;
|
|
||||||
import org.springframework.core.io.Resource;
|
|
||||||
import org.springframework.core.io.ResourceLoader;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Properties used to configure resource handling.
|
* Properties used to configure resource handling.
|
||||||
|
|
@ -36,30 +28,17 @@ import org.springframework.core.io.ResourceLoader;
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
|
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
|
||||||
public class ResourceProperties implements ResourceLoaderAware {
|
public class ResourceProperties {
|
||||||
|
|
||||||
private static final String[] SERVLET_RESOURCE_LOCATIONS = { "/" };
|
|
||||||
|
|
||||||
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
|
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = {
|
||||||
"classpath:/META-INF/resources/", "classpath:/resources/",
|
"classpath:/META-INF/resources/", "classpath:/resources/",
|
||||||
"classpath:/static/", "classpath:/public/" };
|
"classpath:/static/", "classpath:/public/" };
|
||||||
|
|
||||||
private static final String[] RESOURCE_LOCATIONS;
|
|
||||||
|
|
||||||
static {
|
|
||||||
RESOURCE_LOCATIONS = new String[CLASSPATH_RESOURCE_LOCATIONS.length
|
|
||||||
+ SERVLET_RESOURCE_LOCATIONS.length];
|
|
||||||
System.arraycopy(SERVLET_RESOURCE_LOCATIONS, 0, RESOURCE_LOCATIONS, 0,
|
|
||||||
SERVLET_RESOURCE_LOCATIONS.length);
|
|
||||||
System.arraycopy(CLASSPATH_RESOURCE_LOCATIONS, 0, RESOURCE_LOCATIONS,
|
|
||||||
SERVLET_RESOURCE_LOCATIONS.length, CLASSPATH_RESOURCE_LOCATIONS.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locations of static resources. Defaults to classpath:[/META-INF/resources/,
|
* Locations of static resources. Defaults to classpath:[/META-INF/resources/,
|
||||||
* /resources/, /static/, /public/] plus context:/ (the root of the servlet context).
|
* /resources/, /static/, /public/].
|
||||||
*/
|
*/
|
||||||
private String[] staticLocations = RESOURCE_LOCATIONS;
|
private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache period for the resources served by the resource handler, in seconds.
|
* Cache period for the resources served by the resource handler, in seconds.
|
||||||
|
|
@ -73,12 +52,6 @@ public class ResourceProperties implements ResourceLoaderAware {
|
||||||
|
|
||||||
private final Chain chain = new Chain();
|
private final Chain chain = new Chain();
|
||||||
|
|
||||||
private ResourceLoader resourceLoader;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setResourceLoader(ResourceLoader resourceLoader) {
|
|
||||||
this.resourceLoader = resourceLoader;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String[] getStaticLocations() {
|
public String[] getStaticLocations() {
|
||||||
return this.staticLocations;
|
return this.staticLocations;
|
||||||
|
|
@ -97,45 +70,6 @@ public class ResourceProperties implements ResourceLoaderAware {
|
||||||
return normalized;
|
return normalized;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Resource getWelcomePage() {
|
|
||||||
for (String location : getStaticWelcomePageLocations()) {
|
|
||||||
Resource resource = this.resourceLoader.getResource(location);
|
|
||||||
try {
|
|
||||||
if (resource.exists()) {
|
|
||||||
resource.getURL();
|
|
||||||
return resource;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
// Ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String[] getStaticWelcomePageLocations() {
|
|
||||||
String[] result = new String[this.staticLocations.length];
|
|
||||||
for (int i = 0; i < result.length; i++) {
|
|
||||||
String location = this.staticLocations[i];
|
|
||||||
if (!location.endsWith("/")) {
|
|
||||||
location = location + "/";
|
|
||||||
}
|
|
||||||
result[i] = location + "index.html";
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<Resource> resolveFaviconLocations() {
|
|
||||||
List<Resource> locations = new ArrayList<>(this.staticLocations.length + 1);
|
|
||||||
if (this.resourceLoader != null) {
|
|
||||||
for (String location : this.staticLocations) {
|
|
||||||
locations.add(this.resourceLoader.getResource(location));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
locations.add(new ClassPathResource("/"));
|
|
||||||
return Collections.unmodifiableList(locations);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getCachePeriod() {
|
public Integer getCachePeriod() {
|
||||||
return this.cachePeriod;
|
return this.cachePeriod;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
package org.springframework.boot.autoconfigure.web.servlet;
|
package org.springframework.boot.autoconfigure.web.servlet;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
@ -23,6 +25,7 @@ import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
import javax.servlet.Servlet;
|
import javax.servlet.Servlet;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
@ -54,6 +57,7 @@ import org.springframework.boot.context.properties.EnableConfigurationProperties
|
||||||
import org.springframework.boot.web.servlet.filter.OrderedHiddenHttpMethodFilter;
|
import org.springframework.boot.web.servlet.filter.OrderedHiddenHttpMethodFilter;
|
||||||
import org.springframework.boot.web.servlet.filter.OrderedHttpPutFormContentFilter;
|
import org.springframework.boot.web.servlet.filter.OrderedHttpPutFormContentFilter;
|
||||||
import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter;
|
import org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter;
|
||||||
|
import org.springframework.context.ResourceLoaderAware;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
@ -62,7 +66,9 @@ import org.springframework.context.annotation.Primary;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
import org.springframework.core.convert.converter.Converter;
|
import org.springframework.core.convert.converter.Converter;
|
||||||
import org.springframework.core.convert.converter.GenericConverter;
|
import org.springframework.core.convert.converter.GenericConverter;
|
||||||
|
import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.core.io.ResourceLoader;
|
||||||
import org.springframework.format.Formatter;
|
import org.springframework.format.Formatter;
|
||||||
import org.springframework.format.FormatterRegistry;
|
import org.springframework.format.FormatterRegistry;
|
||||||
import org.springframework.format.datetime.DateFormatter;
|
import org.springframework.format.datetime.DateFormatter;
|
||||||
|
|
@ -140,6 +146,8 @@ public class WebMvcAutoConfiguration {
|
||||||
|
|
||||||
public static final String DEFAULT_SUFFIX = "";
|
public static final String DEFAULT_SUFFIX = "";
|
||||||
|
|
||||||
|
private static final String[] SERVLET_LOCATIONS = { "/" };
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
|
@ConditionalOnMissingBean(HiddenHttpMethodFilter.class)
|
||||||
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
|
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
|
||||||
|
|
@ -158,7 +166,7 @@ public class WebMvcAutoConfiguration {
|
||||||
@Configuration
|
@Configuration
|
||||||
@Import(EnableWebMvcConfiguration.class)
|
@Import(EnableWebMvcConfiguration.class)
|
||||||
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
|
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
|
||||||
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
|
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ResourceLoaderAware {
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);
|
private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);
|
||||||
|
|
||||||
|
|
@ -172,6 +180,8 @@ public class WebMvcAutoConfiguration {
|
||||||
|
|
||||||
final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
|
final ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
|
||||||
|
|
||||||
|
private ResourceLoader resourceLoader;
|
||||||
|
|
||||||
public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties,
|
public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties,
|
||||||
WebMvcProperties mvcProperties, ListableBeanFactory beanFactory,
|
WebMvcProperties mvcProperties, ListableBeanFactory beanFactory,
|
||||||
@Lazy HttpMessageConverters messageConverters,
|
@Lazy HttpMessageConverters messageConverters,
|
||||||
|
|
@ -184,6 +194,11 @@ public class WebMvcAutoConfiguration {
|
||||||
.getIfAvailable();
|
.getIfAvailable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResourceLoader(ResourceLoader resourceLoader) {
|
||||||
|
this.resourceLoader = resourceLoader;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
converters.addAll(this.messageConverters.getConverters());
|
converters.addAll(this.messageConverters.getConverters());
|
||||||
|
|
@ -302,18 +317,43 @@ public class WebMvcAutoConfiguration {
|
||||||
customizeResourceHandlerRegistration(
|
customizeResourceHandlerRegistration(
|
||||||
registry.addResourceHandler(staticPathPattern)
|
registry.addResourceHandler(staticPathPattern)
|
||||||
.addResourceLocations(
|
.addResourceLocations(
|
||||||
this.resourceProperties.getStaticLocations())
|
getResourceLocations(this.resourceProperties.getStaticLocations()))
|
||||||
.setCachePeriod(cachePeriod));
|
.setCachePeriod(cachePeriod));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public WelcomePageHandlerMapping welcomePageHandlerMapping(
|
public WelcomePageHandlerMapping welcomePageHandlerMapping() {
|
||||||
ResourceProperties resourceProperties) {
|
return new WelcomePageHandlerMapping(getWelcomePage(),
|
||||||
return new WelcomePageHandlerMapping(resourceProperties.getWelcomePage(),
|
|
||||||
this.mvcProperties.getStaticPathPattern());
|
this.mvcProperties.getStaticPathPattern());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static String[] getResourceLocations(String[] staticLocations) {
|
||||||
|
String[] locations = new String[staticLocations.length + SERVLET_LOCATIONS.length];
|
||||||
|
System.arraycopy(staticLocations, 0, locations, 0, staticLocations.length);
|
||||||
|
System.arraycopy(SERVLET_LOCATIONS, 0, locations,
|
||||||
|
staticLocations.length, SERVLET_LOCATIONS.length);
|
||||||
|
return locations;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Resource> getWelcomePage() {
|
||||||
|
return Arrays.stream(getResourceLocations(this.resourceProperties.getStaticLocations()))
|
||||||
|
.map(location -> this.resourceLoader.getResource(location + "index.html"))
|
||||||
|
.filter(resource -> {
|
||||||
|
try {
|
||||||
|
if (resource.exists()) {
|
||||||
|
resource.getURL();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception ex) {
|
||||||
|
// Ignore
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
.findFirst();
|
||||||
|
}
|
||||||
|
|
||||||
private void customizeResourceHandlerRegistration(
|
private void customizeResourceHandlerRegistration(
|
||||||
ResourceHandlerRegistration registration) {
|
ResourceHandlerRegistration registration) {
|
||||||
if (this.resourceHandlerRegistrationCustomizer != null) {
|
if (this.resourceHandlerRegistrationCustomizer != null) {
|
||||||
|
|
@ -331,14 +371,21 @@ public class WebMvcAutoConfiguration {
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
|
@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
|
||||||
public static class FaviconConfiguration {
|
public static class FaviconConfiguration implements ResourceLoaderAware {
|
||||||
|
|
||||||
private final ResourceProperties resourceProperties;
|
private final ResourceProperties resourceProperties;
|
||||||
|
|
||||||
|
private ResourceLoader resourceLoader;
|
||||||
|
|
||||||
public FaviconConfiguration(ResourceProperties resourceProperties) {
|
public FaviconConfiguration(ResourceProperties resourceProperties) {
|
||||||
this.resourceProperties = resourceProperties;
|
this.resourceProperties = resourceProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setResourceLoader(ResourceLoader resourceLoader) {
|
||||||
|
this.resourceLoader = resourceLoader;
|
||||||
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SimpleUrlHandlerMapping faviconHandlerMapping() {
|
public SimpleUrlHandlerMapping faviconHandlerMapping() {
|
||||||
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
|
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
|
||||||
|
|
@ -351,11 +398,19 @@ public class WebMvcAutoConfiguration {
|
||||||
@Bean
|
@Bean
|
||||||
public ResourceHttpRequestHandler faviconRequestHandler() {
|
public ResourceHttpRequestHandler faviconRequestHandler() {
|
||||||
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
|
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
|
||||||
requestHandler
|
requestHandler.setLocations(resolveFaviconLocations());
|
||||||
.setLocations(this.resourceProperties.resolveFaviconLocations());
|
|
||||||
return requestHandler;
|
return requestHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<Resource> resolveFaviconLocations() {
|
||||||
|
String[] resourceLocations = getResourceLocations(this.resourceProperties.getStaticLocations());
|
||||||
|
List<Resource> locations = new ArrayList<>(resourceLocations.length + 1);
|
||||||
|
Arrays.stream(resourceLocations)
|
||||||
|
.forEach(location -> locations.add(this.resourceLoader.getResource(location)));
|
||||||
|
locations.add(new ClassPathResource("/"));
|
||||||
|
return Collections.unmodifiableList(locations);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -546,9 +601,9 @@ public class WebMvcAutoConfiguration {
|
||||||
private static final Log logger = LogFactory
|
private static final Log logger = LogFactory
|
||||||
.getLog(WelcomePageHandlerMapping.class);
|
.getLog(WelcomePageHandlerMapping.class);
|
||||||
|
|
||||||
private WelcomePageHandlerMapping(Resource welcomePage,
|
private WelcomePageHandlerMapping(Optional<Resource> welcomePage,
|
||||||
String staticPathPattern) {
|
String staticPathPattern) {
|
||||||
if (welcomePage != null && "/**".equals(staticPathPattern)) {
|
if (welcomePage.isPresent() && "/**".equals(staticPathPattern)) {
|
||||||
logger.info("Adding welcome page: " + welcomePage);
|
logger.info("Adding welcome page: " + welcomePage);
|
||||||
ParameterizableViewController controller = new ParameterizableViewController();
|
ParameterizableViewController controller = new ParameterizableViewController();
|
||||||
controller.setViewName("forward:index.html");
|
controller.setViewName("forward:index.html");
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ public class WebFluxAutoConfigurationTests {
|
||||||
SimpleUrlHandlerMapping.class);
|
SimpleUrlHandlerMapping.class);
|
||||||
assertThat(hm.getUrlMap().get("/**")).isInstanceOf(ResourceWebHandler.class);
|
assertThat(hm.getUrlMap().get("/**")).isInstanceOf(ResourceWebHandler.class);
|
||||||
ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap().get("/**");
|
ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap().get("/**");
|
||||||
assertThat(staticHandler.getLocations()).hasSize(5);
|
assertThat(staticHandler.getLocations()).hasSize(4);
|
||||||
assertThat(hm.getUrlMap().get("/webjars/**"))
|
assertThat(hm.getUrlMap().get("/webjars/**"))
|
||||||
.isInstanceOf(ResourceWebHandler.class);
|
.isInstanceOf(ResourceWebHandler.class);
|
||||||
ResourceWebHandler webjarsHandler = (ResourceWebHandler) hm.getUrlMap()
|
ResourceWebHandler webjarsHandler = (ResourceWebHandler) hm.getUrlMap()
|
||||||
|
|
@ -146,7 +146,7 @@ public class WebFluxAutoConfigurationTests {
|
||||||
.isInstanceOf(ResourceWebHandler.class);
|
.isInstanceOf(ResourceWebHandler.class);
|
||||||
ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap()
|
ResourceWebHandler staticHandler = (ResourceWebHandler) hm.getUrlMap()
|
||||||
.get("/static/**");
|
.get("/static/**");
|
||||||
assertThat(staticHandler.getLocations()).hasSize(5);
|
assertThat(staticHandler.getLocations()).hasSize(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -442,7 +442,7 @@ public class WebMvcAutoConfigurationTests {
|
||||||
.withPropertyValues("spring.resources.static-locations=classpath:/static")
|
.withPropertyValues("spring.resources.static-locations=classpath:/static")
|
||||||
.run((context) -> assertThat(
|
.run((context) -> assertThat(
|
||||||
getFaviconMappingLocations(context).get("/**/favicon.ico"))
|
getFaviconMappingLocations(context).get("/**/favicon.ico"))
|
||||||
.hasSize(2));
|
.hasSize(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
||||||
|
|
@ -1900,10 +1900,11 @@ can be achieved as follows:
|
||||||
----
|
----
|
||||||
|
|
||||||
You can also customize the static resource locations using
|
You can also customize the static resource locations using
|
||||||
`spring.resources.static-locations` (replacing the default values with a list of directory
|
`spring.resources.static-locations` (replacing the default values with a list
|
||||||
locations). If you do this the default welcome page detection will switch to your custom
|
of directory locations). The root Servlet context path `"/"` will be automatically
|
||||||
locations, so if there is an `index.html` in any of your locations on startup, it will be
|
added as a location as well. If you do this the default welcome page detection will
|
||||||
the home page of the application.
|
switch to your custom locations, so if there is an `index.html` in any of your locations
|
||||||
|
on startup, it will be the home page of the application.
|
||||||
|
|
||||||
In addition to the '`standard`' static resource locations above, a special case is made
|
In addition to the '`standard`' static resource locations above, a special case is made
|
||||||
for http://www.webjars.org/[Webjars content]. Any resources with a path in `+/webjars/**+`
|
for http://www.webjars.org/[Webjars content]. Any resources with a path in `+/webjars/**+`
|
||||||
|
|
@ -2249,7 +2250,7 @@ Unlike Spring MVC, it does not require the Servlet API, is fully asynchronous an
|
||||||
non-blocking, and implements the http://www.reactive-streams.org/[Reactive Streams]
|
non-blocking, and implements the http://www.reactive-streams.org/[Reactive Streams]
|
||||||
specification through http://projectreactor.io/[the Reactor project].
|
specification through http://projectreactor.io/[the Reactor project].
|
||||||
|
|
||||||
Spring WebFlux comes in two flavors — the annotation-based one is quite close to the
|
Spring WebFlux comes in two flavors; the annotation-based one is quite close to the
|
||||||
Spring MVC model we know:
|
Spring MVC model we know:
|
||||||
|
|
||||||
[source,java,indent=0]
|
[source,java,indent=0]
|
||||||
|
|
@ -3066,7 +3067,7 @@ auto-configured. In this example it's pulled in transitively via
|
||||||
`spring-boot-starter-data-jpa`.
|
`spring-boot-starter-data-jpa`.
|
||||||
|
|
||||||
TIP: If, for whatever reason, you do configure the connection URL for an embedded
|
TIP: If, for whatever reason, you do configure the connection URL for an embedded
|
||||||
database, care should be taken to ensure that the database’s automatic shutdown is
|
database, care should be taken to ensure that the database's automatic shutdown is
|
||||||
disabled. If you're using H2 you should use `DB_CLOSE_ON_EXIT=FALSE` to do so. If you're
|
disabled. If you're using H2 you should use `DB_CLOSE_ON_EXIT=FALSE` to do so. If you're
|
||||||
using HSQLDB, you should ensure that `shutdown=true` is not used. Disabling the database's
|
using HSQLDB, you should ensure that `shutdown=true` is not used. Disabling the database's
|
||||||
automatic shutdown allows Spring Boot to control when the database is closed, thereby
|
automatic shutdown allows Spring Boot to control when the database is closed, thereby
|
||||||
|
|
@ -4573,7 +4574,7 @@ recommend to keep this setting enabled if you create your own `RedisCacheManager
|
||||||
|
|
||||||
[[boot-features-caching-provider-caffeine]]
|
[[boot-features-caching-provider-caffeine]]
|
||||||
==== Caffeine
|
==== Caffeine
|
||||||
Caffeine is a Java 8 rewrite of Guava’s cache that supersede the Guava support. If
|
Caffeine is a Java 8 rewrite of Guava's cache that supersede the Guava support. If
|
||||||
Caffeine is present, a `CaffeineCacheManager` (provided by the
|
Caffeine is present, a `CaffeineCacheManager` (provided by the
|
||||||
`spring-boot-starter-cache` '`Starter`') is auto-configured. Caches can be created
|
`spring-boot-starter-cache` '`Starter`') is auto-configured. Caches can be created
|
||||||
on startup using the `spring.cache.cache-names` property and customized by one of the
|
on startup using the `spring.cache.cache-names` property and customized by one of the
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue