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 ResourceHttpRequestHandlers. 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 ResourceHttpRequestHandlers 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