0

我刚刚使用Spring Boot 初始化程序生成了一个 WAR 打包应用程序,这里是生成的源代码。

主要应用类

@SpringBootApplication
public class ChargingListenerApplication {

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

}

servlet 初始化程序类。

public class ServletInitializer extends SpringBootServletInitializer {

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

}

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

4

2 回答 2

1

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

是的,在 Spring 文档中,它们SpringBootServletInitializer在主类中扩展,但这并不意味着您也不能将它放在其他地方。唯一奇怪的是,他们确实推荐了一件事(在主类中扩展它),但初始化器做了另一件事(创建一个单独的类),但可能是出于清晰的原因。

于 2021-11-10T12:32:47.947 回答
1

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

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

对于 Annotation HandlesTypes,

aServletContainerInitializer表示感兴趣的类。如果 ServletContainerInitializer 的实现指定了此注解,则 Servlet 容器必须将扩展、实现或已使用此注解列出的类类型注解的应用程序类的集合传递给 ServletContainerInitializer.onStartup(java.util.Set>, javax.servlet.ServletContext)ServletContainerInitializer 的方法(如果没有找到匹配的类,必须改为传递 null)

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

ServletContainerInitializer是容器在启动期间运行其所有实现的 servlet 接口(ofc 实现必须通过 META-INF/services/javax.servlet.ServletContainerInitializer 注册)

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

于 2021-11-10T13:42:58.950 回答