spring与Servlet的感情
先来一段背景吧
伴随着servlet3.0的引入
servlet也趋向与基于注解,纯java代码编程的方式
在这里spring也很快的追随了这一特性,进行了跟进,
使得之前的ApplicationContext需要通过xml配置,转而到纯java代码
这里就有很多个注解,这里主要说明的是@Configuration @Bean 以及一些其他的Component注解
注解有了,我们如何启动监听器来让我们的SpringContext启动呢servlet3.0都没有web.xml了,那么spring是如何弄得
直接上代码 spring源码
@HandlesTypes(WebApplicationInitializer.class) public class SpringServletContainerInitializer implements ServletContainerInitializer { @Override public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext) throws ServletException { List<WebApplicationInitializer> initializers = new LinkedList<WebApplicationInitializer>(); if (webAppInitializerClasses != null) { for (Class<?> waiClass : webAppInitializerClasses) { // Be defensive: Some servlet containers provide us with invalid classes, // no matter what @HandlesTypes says... if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) && WebApplicationInitializer.class.isAssignableFrom(waiClass)) { try { initializers.add((WebApplicationInitializer) waiClass.newInstance()); } catch (Throwable ex) { throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex); } } } } if (initializers.isEmpty()) { servletContext.log("No Spring WebApplicationInitializer types detected on classpath"); return; } servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath"); AnnotationAwareOrderComparator.sort(initializers); for (WebApplicationInitializer initializer : initializers) { initializer.onStartup(servletContext); } } }
这里介绍下几个核心
ServletContainerInitializer
servlet3.0提供的动态注册,这里有一个缺点就是只能初始化的时候注册
SpringServletContainerInitializer
这里就是我们spring提供了,其实针对servlet3.0就是用户自定义
WebApplicationInitializer
这个类就是一个接口,和@HandlesType注解一起使用,这个接口可以被SpringServletContainerInitializer 进行处理,然后在onStart()方法中进行操作,因为这个注解提供的参数可以被这个方法所获取
@HandlesTypes
给SpringServletContainerInitializer 的onStart()方法提供入参
这下大致就明白了
也就是spring 对servlet 进行了自定义启动,在spring通过WebApplicationInitializer抽象出来的接口,然后由特殊功能的启动来进行实现,这样的话,在上下文中可以被onStart()进行启动
这里展示几个常用的WebApplicationInitializer接口实现类
AbstractContextLoaderInitializer
AbstractDispatcherServletInitializer
更进一步的
AbstractAnnotationConfigDispatcherServletInitializer
这里还有一个我所了解的 AbstractAnnotationConfigDispatcherServletInitializer
反正大家可以多留意,意思就是,通过这些类,我们就可以去通过servletContext启动来对其增加一些servlet filter listener
然后来启动我们的spring ApplicationContext
启动Spring ApplicationContext 我们不多说了
一个是监听器,一个是过滤器,美美的哈哈