一个ServletContainerInitializer的例子
最近在看Servlet规范3.0,里面有一个接口叫做ServletContainerInitializer,网上关于这个接口使用方法的资料比较少,故而写一篇出来记录一下ServletContainerInitializer的使用方法。
一、什么是ServletContainerInitializer
ServletContainerInitializer是Servlet规范3.0提供的一个新的接口,它有一个方法:
public void onStartup(Set<Class<?>> c, ServletContext ctx)
throws ServletException;
提供这个接口的目的是为了让Servlet的编程人员可以动态的加载,或者修改Servlet,Filter和Listener。
二:如何使用ServletContainerInitializer
既然ServletContainerInitializer是一个接口,那么首先,你当然要为这个接口提供一个实现类,那么Servlet容器是如何加载到这个实现类的呢,按照Servlet规范3.0,你需要WEB-INF的lib包下面有一个jar文件,这个jar文件包含了一个META-INF/services/javax.servlet.ServletContainerInitializer文件,在这个文件里面你需要将你的实现类的全限定类名添加到里面。
另外,你需要一个为你的实现类添加一个HandlesTypes注解,这个注解有一个value值,这个值是一个Class数组,包含了你想要处理的类,容器会扫描出所有匹配这个数组里面的类的类(包含实现,扩展或者被注解的类),然后将这个类所有onStartup的第一个参数传入,然后你就可以处理了
下面我们看一个ServletContainerInitializer的实现类:
/**
* 测试ServletContainerInitializer
*
* @author khotyn 2011-10-8 下午2:54:09
*/
@HandlesTypes(value = { HttpServlet.class })
public class HelloInitializer implements ServletContainerInitializer {
public void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException {
System.out.println("Hello, Initializer!");
for (Class<?> clazz : c) {
if (clazz.getName().contains("ByteServlet")) {
Dynamic dynamic = ctx.addServlet("byte", clazz.getName());
dynamic.addMapping("/byte");
}
}
}
}
容器会扫描出所有实现了HttpServlet这个类的类,如果类名包含了ByteServlet,就动态地加载到容器中去,并将路径映射到”/byte”下。