Home > Software engineering >  Possible Missing Annotation with Spring Boot Initializer
Possible Missing Annotation with Spring Boot Initializer

Time:11-11

I just generated a WAR packaging app with spring boot initializer and here are the generated sources.

Main application class

@SpringBootApplication
public class ChargingListenerApplication {

  public static void main(String[] args) {
    SpringApplication.run(ChargingListenerApplication.class, args);
  }

}

the servlet initializer class.

public class ServletInitializer extends SpringBootServletInitializer {

  @Override
  protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(ChargingListenerApplication.class);
  }

}

How does Spring realize this class and run configure()? Is this just because of the type? If so isn't this a bit weird to handle like this, instead of a proper annotation? Plus, in Spring documentation they extend SpringBootServletInitializer in the main class.

CodePudding user response:

Yes, it is because you are extending SpringBootServletInitializer. It makes use of Spring Framework’s servlet 3.0 support and lets you configure your application when it is launched by the servlet container, which means your custom ServletInitializer.configure() will actually be called.

And yes, in Spring documentation they extend SpringBootServletInitializer in the main class, but that does not mean that you can't also place it someplace else. The only weird thing is that they do recommend one thing (extending it in the main class) but the initializer does another (creating a separate class), but maybe it is on purpose for clarity reasons.

CodePudding user response:

So first of all, Spring-web module has a class SpringServletContainerInitializer which has the definition as below.

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {...}

For the Annotation HandlesTypes,

The classes in which a ServletContainerInitializer has expressed interest. If an implementation of ServletContainerInitializer specifies this annotation, the Servlet container must pass the Set of application classes that extend, implement, or have been annotated with the class types listed by this annotation to the ServletContainerInitializer.onStartup(java.util.Set>, javax.servlet.ServletContext) method of the ServletContainerInitializer (if no matching classes are found, null must be passed instead)

@Target(value=TYPE)
@Retention(value=RUNTIME)
public @interface HandlesTypes {..}

ServletContainerInitializer is servlet interface that a container runs all of it's implementations during the startup (ofc implementations must be registered via META-INF/services/javax.servlet.ServletContainerInitializer )

So, spring checks in registered SpringServletContainerInitializer class for types passed to the it via container and runs their onStartup methods respectively.

  • Related