zoukankan      html  css  js  c++  java
  • Web项目的启动流程

    在web项目的启动过程中,我们希望知道它的一般流程是什么,这样我们就可以在各个流程中加入相应的功能,或者对于我们排错也有帮助。

    1. 启动tomcat容器以后,容器首先初始化一些必要的组件;
    2. 加载项目所引用到的jar包(分别从jdk,tomcat,还有web-inf中的lib目录下);
    3. 读取web项目的web.xml配置文件
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring/root-context.xml,classpath:spring/bwp-context.xml,classpath:spring/csp-context.xml</param-value>
      </context-param>
      <listener>
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
      </listener>
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
      
     <!--  <listener>
        <listener-class>usi.btfb.filter.HttpSessionCollector</listener-class>
      </listener> -->
      
       <!-- session共享过滤器start,此过滤器要放在其他过滤器之前 -->
      <!-- <filter>
         <filter-name>springSessionRepositoryFilter</filter-name>
         <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
       </filter>
      <filter-mapping>
        <filter-name>springSessionRepositoryFilter</filter-name>
         <url-pattern>/*</url-pattern>
       </filter-mapping> -->
       <!-- session共享过滤器end -->
      
      <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:spring/servlet-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <servlet-mapping>
        <servlet-name>appServlet</servlet-name>
        <url-pattern>/</url-pattern>
      </servlet-mapping>
    
     <!--  cxfservlet 
          <servlet>
            <servlet-name>cxf</servlet-name>
            <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>cxf</servlet-name>
            <url-pattern>/service/*</url-pattern>
        </servlet-mapping>-->
    
      <!-- 解决xss & sql漏洞 -->  
      <filter>
        <filter-name>jsFilter</filter-name>
        <filter-class>usi.btfb.filter.SpecialChrEscapeFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>jsFilter</filter-name>
        <url-pattern>*.do</url-pattern>
        <dispatcher>REQUEST</dispatcher>
      </filter-mapping> 
      
      <filter>
        <filter-name>characterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
          <param-name>encoding</param-name>
          <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
          <param-name>forceEncoding</param-name>
          <param-value>true</param-value>
        </init-param>
      </filter>
      <filter-mapping>
        <filter-name>characterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
    
      <servlet>
        <servlet-name>uiLoaderServlet</servlet-name>
        <servlet-class>usi.sys.servlet.UiLoaderServlet</servlet-class>
        <init-param>
          <param-name>uiConfigLocation</param-name>
          <param-value>classpath:ui/ui.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
      </servlet>
      <filter>
        <filter-name>CheckSessionFilter</filter-name>
        <!-- <filter-class>usi.sys.filter.CheckSessionFilter</filter-class> -->
        <filter-class>usi.btfb.filter.CheckSessionFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>CheckSessionFilter</filter-name>
        <url-pattern>*.do</url-pattern>
      </filter-mapping>
        <filter-mapping>
        <filter-name>CheckSessionFilter</filter-name>
        <url-pattern>*.html</url-pattern>
      </filter-mapping>
      <context-param>
        <param-name>menuFilter</param-name>
        <param-value>true</param-value>
      </context-param>
      <filter>
        <filter-name>MenuAccessFilter</filter-name>
        <filter-class>usi.sys.filter.MenuAccessFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>MenuAccessFilter</filter-name>
        <url-pattern>*.do</url-pattern>
      </filter-mapping>
      <filter>
        <filter-name>lazyLoadingFilter</filter-name>
        <filter-class>org.springframework.orm.hibernate4.support.OpenSessionInViewFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>lazyLoadingFilter</filter-name>
        <url-pattern>/*</url-pattern>
      </filter-mapping>
      <filter>
        <filter-name>getSessionContentFilter</filter-name>
        <filter-class>usi.sys.filter.GetSessionContentFilter</filter-class>
      </filter>
      <filter-mapping>
        <filter-name>getSessionContentFilter</filter-name>
        <url-pattern>*.do</url-pattern>
      </filter-mapping>
      <session-config>
        <session-timeout>600</session-timeout>
      </session-config>
      <error-page>
        <error-code>500</error-code>
        <location>/WEB-INF/views/500.jsp</location>
      </error-page>
      <error-page>
        <error-code>404</error-code>
        <location>/WEB-INF/views/404.jsp</location>
      </error-page>
      <error-page>
        <exception-type>java.lang.Throwable</exception-type>
        <location>/WEB-INF/views/500.jsp</location>
      </error-page>
      
      <!--druid监控页面 -->
        <servlet>
            <servlet-name>DruidStatView</servlet-name>
            <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
            <init-param>
                <!-- 不允许清空统计数据 -->
                <param-name>resetEnable</param-name>
                <param-value>false</param-value>
            </init-param>
            <!-- <init-param>
              //  用户名
                <param-name>loginUsername</param-name>
                <param-value>admin</param-value>
            </init-param>
            <init-param>
              //  密码
                <param-name>loginPassword</param-name>
                <param-value>GS_zhkf_2019@</param-value>
            </init-param> -->
        </servlet>
        <servlet-mapping>
            <servlet-name>DruidStatView</servlet-name>
            <url-pattern>/druid/*</url-pattern>
        </servlet-mapping>
        <!-- 如果需要监控uri,设置Web关联监控配置 -->
        <filter>
            <filter-name>DruidWebStatFilter</filter-name>
            <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
            <init-param>
                <param-name>exclusions</param-name><!--排除统计干扰 -->
                <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
            </init-param>
        </filter>
        <filter-mapping>
            <filter-name>DruidWebStatFilter</filter-name>
            <url-pattern>/*</url-pattern>
        </filter-mapping>
        <!--druid监控页面 -->
    </web-app>

    可以看出web.xml的主要配置项有如下几种。

      a.context-param:上下文参数,通过键值对的方式配置一些上下文信息,如contextConfigLocation,我们给他配置为classpath:ApplicationContext.xml,说明去classpath:ApplicationContext.xml这个地方去寻找spring的主配置文件。

      b.listener:listener就是监听器,他会监听一些变化(比如servlet的初始化),然后就可以触发监听器的代码了。

    <listener>
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
      </listener>
    <!--
    1、此监听器主要用于解决java.beans.Introspector导致的内存泄漏的问题
    2、此监听器应该配置在web.xml中与Spring相关监听器中的第一个位置(也要在ContextLoaderListener的前面)
    3、JDK中的java.beans.Introspector类的用途是发现Java类是否符合JavaBean规范如果有的框架或程序用到了Introspector类,那么就会启用一个系统级别的缓存,
    此缓存会存放一些曾加载并分析过的JavaBean的引用。当Web服务器关闭时,由于此缓存中存放着这些JavaBean的引用,所以垃圾回收器无法回收Web容器中的JavaBean对象,最后导致
    内存变大。而org.springframework.web.util.IntrospectorCleanupListener就是专门用来处理Introspector内存泄漏问题的辅助类。IntrospectorCleanupListener会在
    Web服务器停止时清理Introspector缓存,使那些Javabean能被垃圾回收器正确回收。Spring自身不会出现这种问题,因为Spring在加载并分析完一个类之后会马上刷新JavaBeans Introspector缓存,
    这就保证Spring中不会出现这种内存泄漏的问题。但有些程序和框架在使用了JavaBeans Introspector之后,没有进行清理工作(如Quartz,Struts),最后导致内存泄漏
    -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
    <!--
    作用:启动Web容器时,自动装配ApplicationContext的配置信息
    -->

      c.filter:过滤器,顾名思义,就是对请求进行过滤,filter也会在项目启动的时候被实例化。一般一个filter要对应filter-mapping,用于筛选所要执行过滤器中代码的url路径。如果一个filter没有filter-mapping,那它存在的意义就不大,它在web.xml存在的目的纯粹就是为了在项目启动的时候被实例化,从而执行其内部的代码。上述配置文件中的startFilter就是这个作用。

      d.servlet,servlet的配置与filter类似,就是对请求进行拦截,不同的请求分配到不同的servlet类进行处理。

    启动顺序首先是context-param,接着是listener,在接下来是filter,最后才是servlet。

    所以:简单来说:web项目启动经过如下步骤。

      1.项目启动,加载依赖的jar包。

      2.web容器(tomcat)先提供一个全局上下文ServletContext.

      3.web容器去读取web.xml文件,并且运行ContextLoaderListener监听器,该监听器因为实现了ServletContextListener接口,所以当发现容器生成了一个ServletContext实例的时候,便会执行ServletContextListener接口的初始化方法,在该初始化方法中根据contextConfigLocation指定的位置去读取spring的主要配置文件,然后生成web应用上下文WebApplicationContext,并且将其作为一个属性注入到ServletContext中。

      4.初始化WebApplicationContext以后,启动了“业务层”的spring容器,并开始加载病初始化applicationContext配置文件中所扫描的类。

      5.然后就是初始化filter,最后初始化servlet。

      所以说作为web项目,WebApplicationContext的生成必须要在web容器存在的情况下才能实现,因为他需要ServletContext,而ServletContext是web容器生成的。

      

      DispatcherServlet是什么?有什么用。

      简单来说,它就是一个servlet,但是它是一个特殊的servlet,是整个spring mvc框架的核心,他是一个前端servlet,spring mvc经过前端servlet来接受所有的请求,然后再讲具体工作派发给其他的的servlet来具体实现。

    同时,再servlet的配置文件中,我们看到名为SpringMvc的读取了contextConfigLocation所定义的配置文件(classpath:ApplicationContext-mvc.xml),启动了web层的spring容器,在这个容器里,我们初始化了所有的controller类。如控制台打印的日志所示。

      

      由于初始化DispatcherServlet伴随着启动spring mvc容器(即上面所说的web层容器),所以需要较长的时间,所以我们希望在项目启动的时候就进行初始化的操作。这也是我们将load-on-startup项设为1的原因。因为这个属性设为正数的表示在项目启动的时候就初始化,数字越小表明越早初始化。如果我们将其设为负数的话。那么在项目启动的时候,将不会启动spring mvc的容器,而是当我们第一次访问某个controller所对应的action的时候才来加载启动容器,这将会造成较长时间的等待,所以我们一般将load-on-startup设为1.

  • 相关阅读:
    day 66 crm(3) 自创组件stark界面展示数据
    day 65 crm(2) admin源码解析,以及简单的仿造admin组件
    用 Python+nginx+django 打造在线家庭影院
    django -admin 源码解析
    day 64 crm项目(1) admin组件的初识别以及应用
    云链接 接口不允许 情况 解决方法 mysql Host is not allowed to connect to this MySQL server解决方法
    day 56 linux的安装python3 ,虚拟环境,mysql ,redis
    day55 linux 基础以及系统优化
    Codeforces 989 P循环节01构造 ABCD连通块构造 思维对云遮月参考系坐标轴转换
    Codeforces 990 调和级数路灯贪心暴力 DFS生成树两子树差调水 GCD树连通块暴力
  • 原文地址:https://www.cnblogs.com/xiaotang5051729/p/13156741.html
Copyright © 2011-2022 走看看