• web项目启动时,自动执行代码的几种方式


    在项目开发过程中,往往需要一些功能随着项目启动而优先启动,下面我总结几种方式(非spring boot) spring boot的参考 spring boot 学习之路9 (项目启动后就执行特定方法)


    方式一:   ServletContextListener监听器,不懂监听器的可以去网上百度一下servlet的监听器

      

    java 代码如下:
    
    package com.deifeng.huhy.common.run; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import org.slf4j.Logger; import org.slf4j.LoggerFactory;
    public class RunStartOne implements ServletContextListener { private static final Logger LOGGER = LoggerFactory.getLogger(RunStartOne.class); public RunStartOne() {} public void contextDestroyed(ServletContextEvent arg0) {} public void contextInitialized(ServletContextEvent arg0) { try { // 需要实现的功能 System.out.println("随项目启动方式一----------------》"); } catch (Exception e) { LOGGER.error("GreyClientInitListener error", e); } } }

    web.xml配置如下:
      
    <listener><listener-class>com.deifeng.huhy.common.run.RunStartOne</listener-class></listener>
    项目启动如下:
      
    
    

    方式二:  ApplicationListener

      

    代码实现如下:
    package com.deifeng.huhy.common.run;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.context.ApplicationListener;
    import org.springframework.context.event.ContextRefreshedEvent;
    import org.springframework.stereotype.Service;
    
    @Service
    public class RunStartTwo implements ApplicationListener<ContextRefreshedEvent> {
      private static final Log LOGGER = LogFactory.getLog(RunStartTwo.class);
      @Override
      public void onApplicationEvent(ContextRefreshedEvent event) {
        try {
          // 在web项目中(spring mvc),系统会存在两个容器,一个是root application context
          // ,另一个就是我们自己的 projectName-servlet context(作为root application context的子容器)。
          // 这种情况下,就会造成onApplicationEvent方法被执行两次。为了避免这个问题,我们可以只在root
          // application context初始化完成后调用逻辑代码,其他的容器的初始化完成,则不做任何处理。
          if (event.getApplicationContext().getParent() == null) {
            // 需要实现的功能
            System.out.println("随项目启动方式二----------------》");
          }
        } catch (Exception e) {
          LOGGER.error("StartGateServiceData", e);
        }
      }
    }

    启动成功如下:
      
     

     方式三:extends HttpServlet

      

    代码实现:
        public class RunStartThree extends HttpServlet {
          // Servlet的init方法会在Tomcat启动的时候执行
          public void init() throws ServletException {
          // 需要实现的功能
              System.out.println("随项目启动方式三--------------》");
          }
    }
    
    
    web.xml的配置:
        <servlet>
              <servlet-name>init</servlet-name>
              <servlet-class>com.deifeng.huhy.common.run.RunStartThree</servlet-class>
              <load-on-startup>1</load-on-startup>
        </servlet>
    注意: 有人会问为啥不配servlet-map 简单解释一下,这个功能是随着项目启动而启动,我不允许有url能访问到,所以在这就没配置,如果你配上也没问题,不会保错,为了代码的安全性,我就不配做url的映射了


    启动项目成功如图:
      
    
    

    到这,还没结束,不知道有没有人会思考,这三种启动方式有没有先后啊:现在代码都有了,我就在这测一下------------------------------------

      现在我把三种方式都放开:启动项目我们看日志记录就行了

      applicaton      >       listener    > httpServlet

      

      分析:

        这个优先顺序和servlet容器有关,如果你研读过servlet的源码,

        1.web项目中(spring mvc),系统会存在两个容器,一个是root application context。另一个就是我们自己的 projectName-servlet context(作为root application context的子容器)。这种情况下,就会造成onApplicationEvent方法被执行两次。为了避免这个问题,我们可以只在root application context初始化完成后调用逻辑代码,其他的容器的初始化完成,则不做任何处理。【对应于方式二】

        2.系统容器,是root在先  然后就是项目容器,对于servelt的加载顺序   监听器》过滤器 》servlet  的加载机制,所以造成上面那张启动顺序,有时间可以看看servlet源码

        

     

  • 相关阅读:
    dotnetcore3.1 WPF 实现多语言
    dotnetcore3.1 WPF 中使用依赖注入
    [svc]打通mysql主从同步
    [svc]glusterfs的简单部署
    [svc]inotify+rsync解决nfs单点问题
    [svc]rsync简单部署
    [svc]linux文件权限
    [svc]ssh批量分发key/批量用户管理
    [svc]NFS存储企业场景及nfs最佳实战探究
    [svc]mount命令及解决因/etc/fstab错误导致系统不能启动故障
  • 原文地址:https://www.cnblogs.com/huhongy/p/8342203.html
Copyright © 2020-2023  润新知