While migrating from from a 2.x to a 3.x setup we have detected a pretty severe change/bug in the configuration handling.

We have several beans which implement org.springframework.context.ApplicationContextInitializer. These beans were declared as spring factories in the 2.x environment. With this option gone in 3.x they have as per recommendation been migrated to use the AutoConfiguration setup. What we however note is that this new AutoConfiguration setup does not care about the ApplicationContextInitializer interface.

The AutoConfiguration setup also does not honor the org.springframework.core.Ordered interface. These beans should execute as early as possible and in the 2.x environment this works as desired. To give a sense of the "timing", the log output from these beans will be right after the Spring logo in the log.

In the 3.x environment the behavior is totally different. The instantiation of the bean now happens just before the log message about Tomcat starting, that is, almost at the end of the initialization. A debug session shows that the getOrder method stipulated by the Ordered interface is never called. Using AutoConfigurationOrder does not yield any better result.

Also the initialize method stipulated by the ApplicationContextInitializer interface is not called. A debug session confirms that neither method is called. In the end, we end up with dead beans that are not performing what is expected.

We could not find anything in the documentation in regards to how this setup should be changed to work so for now we will assume that this is a bug that needs to be corrected.

This problem was detected in a 3.1.3 setup but it seems like this is an issue for all 3.x setups.

Comparing the code in org.springframework.boot.SpringApplication between 2.x and 3.x reveals that 2.x has a getSpringFactoriesInstances method which works as expected. This method is completely changed in 3.x so obviously the handling has moved and the new handling is not compatible/has a bug.

Comment From: wilkinsona

With this option gone in 3.x

Why do you believe that this option is gone in 3.x? spring.factories is still used by SpringApplication to load ApplicationContextInitializer instances:

https://github.com/spring-projects/spring-boot/blob/9edc7723129ae3c56db332691c0d1d49db7d32d0/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java#L275

What we however note is that this new AutoConfiguration setup does not care about the ApplicationContextInitializer interface

That is to be expected. ApplicationContextInitializer instances are called by SpringApplication before the context is refreshed and before any auto-configuration has begun:

https://github.com/spring-projects/spring-boot/blob/9edc7723129ae3c56db332691c0d1d49db7d32d0/spring-boot-project/spring-boot/src/main/java/org/springframework/boot/SpringApplication.java#L595-L609

Comment From: thoroughsoft

Why do you believe that this option is gone in 3.x?

We "over-interpreted" this section in the migration guide:

Spring Boot 2.7 introduced a new META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports file for registering auto-configurations, while maintaining backwards compatibility with registration in spring.factories. With this release, support for registering auto-configurations in spring.factories has been removed in favor of the imports file.

Anyway, we reverted the relevant code back to use spring.factories and it works as expected.

Thanks to your speedy response I can slam down the cold ones tonight out of happiness instead of despair.

Comment From: wilkinsona

Thanks for letting us know. I've updated the migration guide a little to hopefully clarify the scope of the change:

Spring Boot 2.7 introduced a new META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports file for registering auto-configurations, while maintaining backwards compatibility with registration in spring.factories. With this release, support for registering auto-configurations in spring.factories using the org.springframework.boot.autoconfigure.EnableAutoConfiguration key has been removed in favor of the imports file. Entries in spring.factories under other keys are unaffected.