ServletContainerInitializer初始化器
2016-07-24 14:08
525 查看
在web容器启动时为提供给第三方组件机会做一些初始化的工作,例如注册servlet或者filtes等,servlet规范中通过
一般伴随着
Tomcat容器的
基本的实现机制如图,首先通过ContextConfig监听器遍历每个jar包或web根目录的
假如读出来的内容为
其中
即可获取到HttpServlet和Filter的class对象数组,后面Context容器调用
ServletContainerInitializer实现此功能。每个框架要使用
ServletContainerInitializer就必须在对应的jar包的META-INF/services 目录创建一个名为
javax.servlet.ServletContainerInitializer的文件,文件内容指定具体的
ServletContainerInitializer实现类,那么,当web容器启动时就会运行这个初始化器做一些组件内的初始化工作。
一般伴随着
ServletContainerInitializer一起使用的还有
HandlesTypes注解,通过
HandlesTypes可以将感兴趣的一些类注入到
ServletContainerInitializerde的onStartup方法作为参数传入。
Tomcat容器的
ServletContainerInitializer机制的实现,主要交由Context容器和ContextConfig监听器共同实现,ContextConfig监听器负责在容器启动时读取每个web应用的
WEB-INF/lib目录下包含的jar包的
META-INF/services/javax.servlet.ServletContainerInitializer,以及web根目录下的
META-INF/services/javax.servlet.ServletContainerInitializer,通过反射完成这些
ServletContainerInitializer的实例化,然后再设置到Context容器中,最后Context容器启动时就会分别调用每个
ServletContainerInitializer的onStartup方法,并将感兴趣的类作为参数传入。
基本的实现机制如图,首先通过ContextConfig监听器遍历每个jar包或web根目录的
META-INF/services/javax.servlet.ServletContainerInitializer文件,根据读到的类路径实例化每个
ServletContainerInitializer;然后再分别将实例化好的
ServletContainerInitializer设置进Context容器中;最后Context容器启动时分别调用所有
ServletContainerInitializer对象的onStartup方法。
假如读出来的内容为
com.seaboat.mytomcat.CustomServletContainerInitializer,则通过反射实例化一个
CustomServletContainerInitializer对象,这里涉及到一个
@HandlesTypes注解的处理,被它标明的类需要作为参数值传入到onStartup方法。如下例子:
@HandlesTypes({ HttpServlet.class,Filter.class }) public class CustomServletContainerInitializer implements ServletContainerInitializer { public void onStartup(Set<Class<?>> classes, ServletContext servletContext) throws ServletException { for(Class c : classes) System.out.println(c.getName()); } }
其中
@HandlesTypes标明的HttpServlet和Filter两个class被注入到了onStartup方法。所以这个注解也是需要在ContextConfig监听器中处理。前面已经介绍了注解的实现原理,由于有了编译器的协助,我们可以方便地通过
ServletContainerInitializer的class对象中获取到HandlesTypes对象,进而再获取到注解声明的类数组,如
HandlesTypes ht =servletContainerInitializer.getClass().getAnnotation(HandlesTypes.class); Class<?>[] types = ht.value();
即可获取到HttpServlet和Filter的class对象数组,后面Context容器调用
CustomServletContainerInitializer对象的onStartup方法时作为参数传入。至此,即完成了servlet规范的
ServletContainerInitializer初始化器机制。
相关文章推荐
- ServletContainerInitializer初始化器
- 2016 Multi-University Training Contest 1 1001 Abandoned country
- HDU 5735 Born Slippy ( from:2016 Multi-University Training Contest 2 )
- 服务大众的人工智能---认知服务
- gdb调试core时能用i locals看栈变量、函数行(即不出现No symbol table info available)的必要条件: 1. 编译时有-g参数; 2.so库未被strip脱衣服
- bio nio aio
- 关于inputStream.available()方法获取下载文件的总大小
- 最容易读进去的深度学习科普贴
- LeetCode 172. Factorial Trailing Zeroes
- gipchaInternalResolve:failed to resolve ret gipcretKeyNotFound(36),
- 刨一刨内核container_of()的设计精髓
- MapReduce Main Points
- AC again
- 2016 Multi-University Training Contest 2 H Helter Skelter (hdu5741) 【二分】
- HDU-1848 Fibonacci again and again(组合游戏)
- 1079. Total Sales of Supply Chain (25)
- 2015 Multi-University Training Contest 3
- This is probably because there is no OLE editor registered against the type of file you were trying to open.
- mybaits逆向工程
- 219. Contains Duplicate II