Tomcat 服务器具体加载servlet详细介绍(上)

124 阅读3分钟

1.tomcat 服务器作为一个web服务器,它遵循servlet 的规范:

1.web服务器可以访问任何一个web应用中实现了servlet接口的类。

2.web应用中被web 服务器动态调用的程序位于servlet 的实现类中

2.tomcat 服务器中包含

<Server>
   <service>
    <connector>  ## 客户端与服务器之间的通信接口
    </connector>
    <engine>  ## 容器类元素
        <host></host> ## 为特定的主机处理客户请求
    <context></context> ## 为特定的web应用处理客户请求
    <cluster></cluster> ## 集群复制会话,复制属性
    </engine>
  </service>
</server>

3.tomcat 服务器【servlet 容器】初始化servlet

1.将servlet的类 .class 文件读到内存中

2.创建servletConfig 对象,把web.xml 中的配置信息设置到servletConfig 对象中,同时将servletContext对象也设置好。

3.创建servlet对象

4.调用servlet 的init(ServletConfig config) 方法。

根据GenericServlet 的实现来看

public abstract class GenericServlet implements Servlet, ServletConfig,
        java.io.Serializable {
    private transient ServletConfig config;
    ## 实现了ServletConfig 以下4接口
    #public String getServletName();
    @Override
    public String getServletName() {
        return config.getServletName();
    }
    #public ServletContext getServletContext(); 
    @Override
    public ServletContext getServletContext() {
        return getServletConfig().getServletContext();
    }
    # public String getInitParameter(String name);
    @Override
    public String getInitParameter(String name) {
        return getServletConfig().getInitParameter(name);
    }
    #public Enumeration<String> getInitParameterNames();
    
    @Override
    public Enumeration<String> getInitParameterNames() {
        return getServletConfig().getInitParameterNames();
    }
    
    ## 实现了Servlet 的 除了service()以外的所有的接口 其中关键点就是init 的时候将config 
    ##参数赋值给了自己的成员变量config ,而上面那四个接口都是根据config才能拿到 比如 getInitParameter 就是获取servlet 生命的init-param 参数
    ## getServletContext() 就是获取全局的 servletContext,所以每个servlet 都可以拿到 共享的ServletContext()
    ## 有了全局的servletContext 就可以将需要共享的属性通过 setAttribute() getAttribute() 来共享获取了
    @Override
    public ServletConfig getServletConfig() {
        return config;
    }
    @Override
    public String getServletInfo() {
        return "";
    }
    @Override
    public void init(ServletConfig config) throws ServletException {
        this.config = config;
        this.init();
    }
    @Override
    public void destroy() {
        // NOOP by default
    }
    
    ## 定义的新的方法 调用全局的servletContext 的log 方法
    public void log(String message, Throwable t) {
        getServletContext().log(getServletName() + ": " + message, t);
    }
    
    public void log(String message, Throwable t) {
        getServletContext().log(getServletName() + ": " + message, t);
    }
}

4.ServletContextListener 监听器

监听servletContext 的生命周期。在servlet容器启动或者终止web应用时,会触发ServletContextEvent 事件。

contextInitialized(ServletContextEvent sce; servlet 容器启动web应用程序时先调用这个方法,然后再初始化filter 和servlet

contextDestroyed(ServletContextEvent sce); 当servlet 容器终止web应用程序时,先销毁所有的servlet 和filter 然后调用此方法

在web.xml 中 添加

<listener>
    <listener-class>com.whds.pro.ContextLoaderListener</listerner-class>
</listener>

在servlet 容器中,ServletContext 对象,最早被创建,最晚被销毁

5.过滤器 Filter

1.过滤器能够在web组件被调用检查servletRequest 对象,修改请求头和请求正文的内容,或者对请求进行预处理

2.能够在web组件被调用后检查servletResponse对象,修改响应投和响应正文

  1. 过滤器的创建过程

1.将Filter的类 .class 文件读到内存中

2.创建filterConfig 对象,把web.xml 中的配置信息设置到filterConfig 对象中,同时将servletContext对象也设置好。

3.创建filter对象

4.调用filter 的init(FilterConfig filterConfig) 方法。

public abstract class GenericFilter implements Filter, FilterConfig, Serializable {

    private static final long serialVersionUID = 1L;

    private volatile FilterConfig filterConfig;


    @Override
    public String getInitParameter(String name) {
        return getFilterConfig().getInitParameter(name);
    }


    @Override
    public Enumeration<String> getInitParameterNames() {
        return getFilterConfig().getInitParameterNames();
    }


    /**
     * Obtain the FilterConfig used to initialise this Filter instance.
     *
     * @return The config previously passed to the {@link #init(FilterConfig)}
     *         method
     */
    public FilterConfig getFilterConfig() {
        return filterConfig;
    }


    @Override
    public ServletContext getServletContext() {
        return getFilterConfig().getServletContext();
    }

    /** servlet容器
    */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig  = filterConfig;
        init();
    }


    /**
     * Convenience method for sub-classes to save them having to call
     * <code>super.init(config)</code>. This is a NO-OP by default.
     *
     * @throws ServletException If an exception occurs that interrupts the
     *         Filter's normal operation
     */
    public void init() throws ServletException {
        // NO-OP
    }


    @Override
    public String getFilterName() {
        return getFilterConfig().getFilterName();
    }
}

5.web.xml 中发布filter 的一般配置

<filter>
<filter-name> </filter-name>
<filter-class> </filter-class>
<init-param>
    <param-name>    </param-name>
    <param-value>     </param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name> </filter-name>
<url-pattern>  </url-pattern>
</filter-mapping>