Spring 引导初始化程序可能缺少注释

Possible Missing Annotation with Spring Boot Initializer

我刚刚用 spring boot initializer 生成了一个 WAR 打包应用程序,这里是生成的源。

主应用程序class

@SpringBootApplication
public class ChargingListenerApplication {

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

}

servlet 初始化程序 class。

public class ServletInitializer extends SpringBootServletInitializer {

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

}

Spring如何实现这个class和运行configure()?这仅仅是因为类型吗?如果是这样,这样处理而不是正确的注释是不是有点奇怪?另外,在 Spring 文档中,他们在主 class.

中扩展了 SpringBootServletInitializer

是的,那是因为你在扩展SpringBootServletInitializer。它利用 Spring Framework 的 servlet 3.0 支持,并允许您在 servlet 容器启动应用程序时配置您的应用程序,这意味着您的自定义 ServletInitializer.configure() 实际上会被调用。

是的,在 Spring 文档中,它们在主要 class 中扩展了 SpringBootServletInitializer,但这并不意味着您不能将它也放在其他地方。唯一奇怪的是他们确实推荐了一件事(在主要 class 中扩展它)但初始化程序做了另一件事(创建一个单独的 class),但也许是为了清楚起见。

所以首先,Spring-web 模块有一个 class SpringServletContainerInitializer 其定义如下。

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

对于注释句柄类型,

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 )

因此,spring 检查已注册的 SpringServletContainerInitializer class 通过容器传递给它的类型,并分别运行它们的 onStartup 方法。