`

ServletContainerInitializer

    博客分类:
  • web
 
阅读更多

 

在web容器启动时为提供给第三方组件机会做一些初始化的工作,例如注册servlet或者filtes等,servlet规范中通过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初始化器机制。

分享到:
评论

相关推荐

    解决maven启动Spring项目报错的问题

    java.lang.ClassCastException: org.springframework.web.SpringServletContainerInitializer cannot be cast to javax.servlet.ServletContainerInitializer 出现这个报错的原因是 javax.servlet-api 在运行时将 ...

    myservlet.zip

    在这个示例中,`MyServletInitializer`实现了`ServletContainerInitializer`接口,并在应用启动时注册了`MyServlet`,并为其分配了URL映射。 在所有这些实现方式中,`doGet`和`doPost`方法是Servlet处理HTTP请求的...

    Spring+SpringMVC配置加载顺序1

    在 JavaConfig 方式下,这个配置过程依赖于Servlet 3.0 规范中的 ServletContainerInitializer (SC) 接口。当应用在支持Servlet 3.0 的容器(如Tomcat 7及以上版本)中运行时,容器会自动寻找实现了 SC 接口的类。...

    servlet相关资料介绍.zip

    自Servlet 3.0开始,引入了一些新特性,如注解驱动的配置、异步处理、ServletContainerInitializer等,使得开发更加灵活高效。 1. 注解配置:可以直接在Servlet类上使用`@WebServlet`注解进行配置,无需在web.xml中...

    jsp工厂模式jsp工厂模式

    创建自定义Servlet工厂需要实现`javax.servlet.ServletContainerInitializer`接口,并在该接口的`onStartup`方法中注册自定义的Servlet工厂。这样,服务器将在启动时调用该方法,使得我们有机会在程序启动阶段就设置...

    Android i-jetty开源项目.zip

    2. **部署Servlet**:通过`ServletHolder`和`ServletContainerInitializer`部署Servlet,定义处理特定URL路径的逻辑。 3. **启动服务器**:调用`Server`的`start()`方法启动服务器,监听指定端口。 4. **停止...

    Servlet、Filter、Listener深入理解.docx

    4. `ServletContainerInitializer`: 自动注册Servlet和Filter。 通过Servlet、Filter和Listener,开发者可以构建高度定制化的Web应用程序,实现更精细的控制和扩展性。它们共同构成了Java Web应用的基石,帮助...

    跟开涛学SpringMVC(3)DispatcherSer

    8. **自定义配置**:开发者可以通过实现ServletContainerInitializer接口,或在Java配置类中使用`@WebServlet`注解,对DispatcherServlet进行更灵活的配置。 9. **优化与性能**:理解DispatcherServlet的工作原理,...

    Spring MVC总结(一)

    * 使用javax.servlet.ServletContainerInitializer(listing 3) * 如果使用Spring 3.1,可以通过实现WebApplicationInitializer接口(listing 4) 在项目中,每一个模块一个jar包,可以在该jar包中使用web-...

    ervlet3的两个特性共5页.pdf.zip

    5. **ServletContainerInitializer**:这个接口允许开发者定义自己的初始化逻辑,以便在应用启动时执行特定的配置或注册。 6. **Filter Chain Improvements**:Servlet3的过滤器链支持声明多个过滤器应用于同一个...

    基于servlet3.1,实现模块化扩展.zip

    8. **动态注册**:在运行时,可以通过`ServletContainerInitializer`接口动态地注册Servlet、过滤器和监听器,增强了程序的动态性。 9. **资源注入**:Servlet 3.1支持JSR 330标准的依赖注入,可以使用`@Inject`...

    采用Java SPI和Spring factories来实现插件化的demo

    在Java中,SPI通常涉及到`META-INF/services`目录下的特定文件,例如`javax.servlet.ServletContainerInitializer`。开发者可以在这些文件中列出自己的服务实现类,当程序运行时,Java会自动加载这些类,从而实现...

    SpringMVC4进行0配置说明1

    Spring通过`ServletContainerInitializer`接口的实现类`SpringServletContainerInitializer`在容器启动时加载配置。 9. **WebApplicationInitializer**:Spring提供了`WebApplicationInitializer`接口的实现,如`...

    jboss jar包snowdrop-vfs.jar和jboss-logging.jar

    5. 使用合适的容器适配器,如Spring的ContextLoaderListener或ServletContainerInitializer,来正确初始化Spring应用上下文。 总的来说,"snowdrop-vfs.jar" 和 "jboss-logging.jar" 这两个jar包是解决Spring与...

    Java Web阶段笔试和机试试卷_jsp_servlet.pdf

    3. 四种Listener包括:HttpSessionListener、ServletRequestListener、ServletContextListener和ServletContainerInitializer,分别用于监听Session、Request、应用上下文的创建与销毁。 4. Servlet的生命周期包括...

    servlet 3.0 规范提案

    `ServletContainerInitializer`接口允许实现自定义的初始化逻辑,用于在应用启动时注册组件。 5. **WebSocket支持**: - 虽然不是Servlet 3.0的核心特性,但WebSocket API是在Servlet 3.0规范中首次引入的,为低...

    第七节 渐行渐远的 Servlet1

    另外,Servlet 3.0引入的`ServletContainerInitializer`接口允许自定义初始化逻辑,使得应用启动时可以自动注册组件。 总之,Servlet作为Web开发中的关键组件,其发展历程反映了Web技术的演进,从最初的CGI替代方案...

    tomcat6到8windows版本.zip

    - 引入了ServletContainerInitializer接口,允许第三方库进行自定义初始化。 - 提高了线程池管理,增强了并发性能,支持更多的并发用户请求。 - 引入了ContextPath、Path、ServletPath和RequestURI的独立路径元素...

    Spring注解驱动开发实战-servlet

    首先,让我们来理解`ServletContainerInitializer`。这是一个Java EE 7引入的接口,允许我们自定义初始化Servlet容器的行为。通过实现这个接口并使用`@HandlesTypes`注解来指定关心的类类型,我们可以当这些类型被...

    javax.servlet-api-3.1.0.jar

    此外,还包括了Servlet生命周期管理的接口,如Servlet、ServletConfig和ServletContainerInitializer,它们帮助服务器管理和加载Servlet实例。 在实际开发中,将`javax.servlet-api-3.1.0.jar`作为项目的依赖,可以...

Global site tag (gtag.js) - Google Analytics