spring boot:servlet启动方式
serlvlet 3.0
在web容器启动时为提供给第三方组件机会做一些初始化的工作,例如注册servlet或者filtes等,servlet规范中通过ServletContainerInitializer实现此功能。每个框架要使用ServletContainerInitializer就必须在对应的jar包的META-INF/services 目录创建一个名为javax.servlet.ServletContainerInitializer的文件,文件内容指定具体的ServletContainerInitializer实现类,那么,当web容器启动时就会运行这个初始化器做一些组件内的初始化工作。
一般伴随着ServletContainerInitializer一起使用的还有HandlesTypes注解,通过HandlesTypes可以将感兴趣的一些类注入到ServletContainerInitializerde的onStartup方法作为参数传入。
spring实现的ServletContainerInitializer
spring-web-xx.jar中,在META-INF/service目录下配置了ServletContainerInitializer的实现类org.springframework.web.SpringServletContainerInitializer
SpringServletContainerInitializer
@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
// servlet容器会将@HandlesTypes注解中实现类作为参数传进来
@Override
public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
throws ServletException {
// 代码有删减
List<WebApplicationInitializer> initializers = new LinkedList<>();
for (Class<?> waiClass : webAppInitializerClasses) {
// 过滤掉接口和抽象类
if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
initializers.add((WebApplicationInitializer)ReflectionUtils.accessibleConstructor(waiClass).newInstance());
}
}
// 调用WebApplicationInitializer实现类的初始化方法
for (WebApplicationInitializer initializer : initializers) {
initializer.onStartup(servletContext);
}
}
}
WebApplicationInitializer的实现类有一下几种,可以通过扩展任何一个类,来实现自己想要的配置。
SpringBootServletInitializer
SpringBootServletInitializer的onStartup方法中会创建spring的WebApplicationContext,进而实现通过web.xml配置中ContextLoaderListener实现的spring上下文的加载
比如:
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
// 代码有删减
WebApplicationContext rootApplicationContext = createRootApplicationContext(servletContext);
servletContext.addListener(new SpringBootContextLoaderListener(rootApplicationContext, servletContext));
}
SpringBootServletInitializer是抽象类,工程中可以通过覆盖protected SpringApplicationBuilder configure(SpringApplicationBuilder builder)来进行自定义的配置。
比如,传入根配置
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(MyApplication.class);
}
}
本文地址:https://blog.csdn.net/shuxiaohua/article/details/109643696