在web容器启动时为提供给第三方组件机会做一些初始化的工作,例如注册servlet或者filtes等,servlet规范中通过ServletContainerInitializer实现此功能。
每个框架要使用ServletContainerInitializer就必须在对应的jar包的META-INF/services 目录创建一个名为javax.servlet.ServletContainerInitializer的文件,文件内容指定具体的ServletContainerInitializer实现类。
每个框架要使用ServletContainerInitializer就必须在对应的jar包的META-INF/services 目录创建一个名为javax.servlet.ServletContainerInitializer的文件,文件内容指定具体的ServletContainerInitializer实现类。
一般伴随着ServletContainerInitializer一起使用的还有HandlesTypes注解,通过HandlesTypes可以将感兴趣的一些类注入到ServletContainerInitializerde的onStartup方法作为参数传入。
@HandlesTypes(value = {TestService.class}) //容器启动的时候会将@HandlesTypes指定的这个类型下面的子类(实现类,子接口等)传递过来 public class TestServletContainerInitializer implements ServletContainerInitializer { //set 父类感兴趣的子类类 @Override public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException { System.out.println("感兴趣的类型"); for(Class<?> classs:set){ System.out.println(classs); } } }
tomcat容器启动时会扫描 service下的 ServletContainerInitializer
手动注册三大组件
public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException { System.out.println("感兴趣的类型"); for(Class<?> classs:set){ System.out.println(classs); } //注册三大组件 //servlet ServletRegistration.Dynamic testServlet = servletContext.addServlet("testServlet", new TestServlet()); testServlet.addMapping("/testServlet"); //listener servletContext.addListener(TestListener.class); //filter FilterRegistration.Dynamic testFilter = servletContext.addFilter("testFilter", TestFilter.class); //注册filter的映射信息,可以指定专门来拦截哪个servlet testFilter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST),true,"/*"); }
spring mvc 在容器启动时也是这样