在SpringMVC框架中,Servlet3.0 容器Tomcat中自动加载Filter和Listener的方式
1、前言:
在SpringMVC中,需要我们实现WebApplicationInitializer接口,来配置SpringMVC核心控制器DispatcherServlet。 Tomcat(Servlet3.0规范的web容器)启动时,会查找ServletContainerInitializer接口实现类
- => SpringServletContainerInitializer类(Spring提供)
- => WebApplicationInitializer接口实现类
- => AbstractContextLoaderInitializer抽象实现类(准备监听器的加载)
- =>AbstractDispatcherServletInitializer抽象实现类(准备过滤器的加载)
- =>AbstractAnnotationConfigDispatcherServletInitializer(准备 RootApplicationContext容器和ServletApplicationContext容器)
- => DispatcherServletConfig(当前类)
- 来完成DispatcherServlet核心控制器的配置
2、过滤器的加载:
而抽象实现类AbstractContextLoaderInitializer,有直接继承的抽象实现子类 AbstractDispatcherServletInitializer,该类完成了过滤器的加载工作。 在该类中,有onStartup方法,在此方法中调用了自己的父类的onStartup()方法, 准备了监听器的加载(详见3),更调用了本类的registerContextLoaderListener()方法完成了监听器加载。
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
registerDispatcherServlet(servletContext);
}
protected void registerDispatcherServlet(ServletContext servletContext) {
String servletName = getServletName();
Assert.hasLength(servletName, "getServletName() must not return null or empty");
WebApplicationContext servletAppContext = createServletApplicationContext();
Assert.notNull(servletAppContext, "createServletApplicationContext() must not return null");
FrameworkServlet dispatcherServlet = createDispatcherServlet(servletAppContext);
Assert.notNull(dispatcherServlet, "createDispatcherServlet(WebApplicationContext) must not return null");
dispatcherServlet.setContextInitializers(getServletApplicationContextInitializers());
ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet);
if (registration == null) {
throw new IllegalStateException("Failed to register servlet with name '" + servletName + "'. " +
"Check if there is another servlet registered under the same name.");
}
registration.setLoadOnStartup(1);
registration.addMapping(getServletMappings());
registration.setAsyncSupported(isAsyncSupported());
Filter[] filters = getServletFilters();
if (!ObjectUtils.isEmpty(filters)) {
for (Filter filter : filters) {
registerServletFilter(servletContext, filter);
}
}
customizeRegistration(registration);
}
3、监听器的加载:
WebApplicationInitializer接口,有直接继承的抽象实现子类AbstractContextLoaderInitializer,其中有实例方法完成了监听器的加载工作。 在该类中,有onStartup方法,
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
registerContextLoaderListener(servletContext);
}
该方法中,调用了registerContextLoaderListener()方法完成了监听器加载。
protected void registerContextLoaderListener(ServletContext servletContext) {
WebApplicationContext rootAppContext = createRootApplicationContext();
if (rootAppContext != null) {
ContextLoaderListener listener = new ContextLoaderListener(rootAppContext);
listener.setContextInitializers(getRootApplicationContextInitializers());
servletContext.addListener(listener);
}
else {
logger.debug("No ContextLoaderListener registered, as " +
"createRootApplicationContext() did not return an application context");
}
}
|