Original issue here: https://github.com/thymeleaf/thymeleaf-spring/issues/227
It seems like cache-busting does not work when lazy initialization is active. Once I set it to false cache-busting works again.
This seems like a bug for the docs say:
In a web application, enabling lazy initialization will result in many web-related beans not being initialized until an HTTP request is received.
But this does not seem to be true for whatever component is responsible for spring.resources.chain.strategy.content
.
Spring boot versions tested: 2.2.2 and 2.2.6
Tested with Thymeleaf
Miminal setup:
Check out https://github.com/ultraq/gs-serving-web-content/tree/cache-busting-issue/complete (branch cache-busting-issue).
In application.properties
:
spring.resources.cache.cachecontrol.max-age=604800
spring.resources.chain.enabled=true
spring.resources.chain.strategy.content.enabled=true
spring.resources.chain.strategy.content.paths=/**
spring.resources.chain.html-application-cache=true
# toggle this on/off
#spring.main.lazy-initialization=true
Maybe this behaviour is intended / to be expected - if so please add a paragraph to the docs.
Comment From: wilkinsona
When resourceHandlerMapping
is lazy, ResourceUrlProvider.detectResourceHandlers(ApplicationContext)
doesn't find it and, therefore, can't extract its ResourceHttpRequestHandler
s. This leaves it with an empty handlerMap
so getForLookupPath(String)
can't get the handler's ResourceResolverChain
and use it for URL path resolution.
The problem can be worked around by ensuring that resourceHandlerMapping
is eagerly initialised:
@Bean
public LazyInitializationExcludeFilter eagerResourceHandlerMapping() {
return (name, definition, type) -> "resourceHandlerMapping".equals(name);
}
Comment From: wilkinsona
I think this may be a Framework bug. WebMvcConfigurationSupport
defines resourceHandlerMapping
as a HandlerMapping
yet ResourceUrlProvider.detectResourceHandlers(ApplicationContext)
tries to discover it by looking for SimpleUrlHandlerMapping
beans. This means that the resource handler detection relies upon being called after resourceHandlerMapping
has been created so that the bean factory can identify that it's a SimpleUrlHandlerMapper
rather than the less-specific HandlerMapping
that it is defined as.
I think a similar problem could arise without lazy init if WebMvcConfigurationSupport
was sub-classed and resourceHandlerMapping
was overridden to return a HandlerMapping
that isn't a SimpleUrlHandlerMapping
. That would prevent ResourceUrlProvider.detectResourceHandlers(ApplicationContext)
from finding it, even if it was an AbstractUrlHandlerMapping
that defines the getHandlerMap()
method that resource handler detection requires.
I wonder if detectResourceHandlers(ApplicationContext)
should get all HandlerMapping
beans, filter out those that are not an AbstractUrlHandlerMapping
or perhaps SimpleUrlHandlerMapping
, and then proceed with extracting the ResourceHttpRequestHandler
s as it does at the moment.
Comment From: snicoll
I've pushed a proposal for this in https://github.com/snicoll/spring-framework/commit/33d15ddf669e00c8c0a8e1598ec2e043a655b72f