Spring Boot - Prioritize Bean Creation Order from External Jar

Viewed 640

I have the following auto-configured class, listed in spring.factories under EnableAutoConfiguration and packaged as a common library:

@Configuration
public class GracefulShutdownConfig {

    @Bean
    public GracefulShutdown gracefulShutdown() {
        return new GracefulShutdown();
    }

    @Bean
    public WebServerFactory webServerFactory(final GracefulShutdown gracefulShutdown) {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.addConnectorCustomizers(gracefulShutdown);
        return factory;
    }
}

When imported as a jar library, the beans get initialized too late, at the point at which the TomcatServletWebServerFactory has already started Tomcat, added the connectorCustomizers and injected a Connector to them.

As a result, the GracefulShutdown class does not receive its Connector and throws a NullPointerException.

I have read solutions on how to prioritize auto-configured classes among auto-configured classes, but in my case I wish the beans of my auto-configured class to get loaded with priority when the Spring Boot itself is starting, as the beans are not related to or dependent on other externally injected beans. Can someone help?

1 Answers

The solution was to use @AutoConfigureBefore.

@AutoConfigureBefore, when used on the Spring auto-configuration class ServletWebServerFactoryAutoConfiguration, which is responsible for the instantiation of TomcatServletWebServerFactory, allows us to register our own BeanDefinition of TomcatServletWebServerFactory before the factory creates its definition

Here is the solution:

@Configuration
@AutoConfigureBefore(value = {ServletWebServerFactoryAutoConfiguration.class})
public class GracefulShutdownConfig {

    @Bean
    public GracefulShutdown gracefulShutdown() {
        return new GracefulShutdown();
    }

    @Bean
    public TomcatServletWebServerFactory webServerFactory(final GracefulShutdown gracefulShutdown) {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.addConnectorCustomizers(gracefulShutdown);
        return factory;
    }
}

Here are two sources that helped me search in the right direction:

Related