开发者

spring中实现容器加载完成后再执行自己的方法

目录
  • spring容器加载完成后再执行自己的方法
    • 应用场景
    • 解决方案如下    
  • spring容器加载完成之后进行开启一个线程进行数据更新操作
    • 总结

      spring容器加载完成后再执行自己的方法

      在开发过程中遇到了要在项目启动后自动开启某个服务,由于使用了spring,我在使用了spring的 listener ,它有 onApplicationEvent ()方法, 在Spring容器将所有的Bean都初始化完成之后,就会执行该方法 。

      应用场景

      很多时候我们想要在某个类加载完毕时干某件事情,但是使用了spring管理对象,我们这个类引用了其他类(可能是更复杂的关联),所以当我们去使用这个类做事情时发现包空指针错误,这是因为我们这个类有可能已经初始化完成,但是引用的其他类不一定初始化完成,所以发生了空指针错误

      解决方案如下    

      1.写一个类继承spring的ApplicationListener监听,并监控ContextRefreshedEvent事件(容易初始化完成事件)    

      2.定义简单的bean:<bean id="startListener" class="com.itsm.core.service.table.StartListener"></bean> 或者直接使用@Service注解方式

      @Service
      public class StartListener implements ApplicationListener<ContextRefreshedEvent> {
        public static final Map<Integer, TableMapper> mappers = new HashMap<>();
        @Resource
        A_Mapper a_mapper;
        @Override
        public void onApplicationEvent(ContextRefreshedEvent event)
        {
          if(event.getApplicationContext().getParent() == null)//root application context 没有parent,他就是老大.
          {
            //需要执行的逻辑代码,当spring容器初始化完成后就会执行该方法。
            System.out.println("\n\n\n\n\n______________\n\n\n加载了\n\n_________\n\n");
          }
          //或者下面这种方式
          if(event.getApplicationContext().getDisplayName().equals("Root WebApplicationContext"))
          {
            System.out.println("\n\n\n_________\n\n加载一次的 \n\n ________\n\n\n\n");
          }
          mappers.put(1,a_mapper);
        }
      }

      spring容器加载完成之后进行开启一个线程进行数据更新操作

      需求:最近做项目遇到了一个需求,数据表中有些数据需要定时更新,这样就需要启动一个线程完成,不想再新建一个项目来完成这些www.devze.com事,就想在spring启动之后来开启一个线程定时来完成这件事 ,直接上代码

      package com.irisian.picturelabel.listenerfSOCLLtk;
      
      import com.irisian.picturelabel.service.PictureService;
      import com.irisian.picturelabel.service.TaskService;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import org.springframework.beans.factory.InitializingBean;
      import org.springframework.beans.factory.annotation.Autowired;
      import org.springframework.stereotype.Component;
      
      /**
      * Author:吴满心
      * Date:2018/5/18
      * Function:负责在spring容器加载完成之后进行图片和任务数据表的更新
      */
      @Component
      public class SpringFinishedListener implements InitializingBean {
        private static final Logger logger = LoggerFactory.getLogger(SpringFinishedListener.class);
      
        @Autowired
        private PictureService pictureService;
      
        @Autowired
        private TaskService taskService;
      
        @Override
        public void afterPropertiesSet() throws Exception {
          new Thread(() -> {
            while (true) {
              logger.info("开始执行图片和任务的更新操作!");
              try {
                pictureService.updatePictureStatus();
                //更新任务的完成状态信息
                taskService.updateFinishStatus();
              } catch (Exception e) {
                e.printStackTrace();
                logger.error(e.getMessage());
              }
              try {
                Thread.sleep(1800000);   //30分钟执行一次进行数据更新
              } catch (InterruptedException e) {
                e.printStackTrace();
                lo编程客栈gger.error(e.getMessage());
              }
            }
          }).start();
      
      
        }
      }

      开始还尝试过servlet的方法,如

      package com.irisian.picturelabel.servlet;
      
      impohttp://www.devze.comrt org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      
      import Javax.servlet.ServletException;
      import javax.servlet.annotation.WebServlet;
      im开发者_Go培训port javax.servlet.http.HttpServlet;
      
      /**
      * Author:吴满心
      * Date:2018/5/18
      * Function:
      */
      @WebServlet(name = "backServlet", urlPatterns = {"/backServlet"})
      public class BackServlet extends HttpServlet {
        private static final Logger logger= LoggerFactory.getLogger(BackServlet.class);
      
        @Override
        public void init() throws ServletException {
          new Thread(()->{
            while(true){
              logger.info("我5秒钟执行一次");
              try {
                Thread.sleep(5000);
              } catch (InterruptedException e) {
                logger.error(e.getMessage());
              }
            }
          }).start();
        }
      
      
        @Override
        public void destroy() {
          logger.info("服务器关闭了");
        }
      }

      配置Configuration

      package com.irisian.picturelabel.configuration;
      import com.irisian.picturelabel.exception.MyExceptionResolver;
      import com.irisian.picturelabel.servlet.BackServlet;
      import org.springframework.boot.web.servlet.ServletRegistrationBean;
      import org.springframework.context.annotation.Bean;
      import org.springframework.context.annotation.Configuration;
      import org.springframework.web.servlet.HandlerExceptionResolver;
      
      /**
      * Author:吴满心
      * Date:2018/5/15
      * Function:
      */
      @Configuration
      public class SpringConfiguration {
        @Bean
        public HandlerExceptionResolver getHandlerExceptionResolver() {
          return new MyExceptionResolver();
        }
      
        /**
        * 配置一个后台运行的servlet
        * @return
        */
        @Bean
        public ServletRegistrationBean servletRegistrationBean() {
          ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new BackServlet(), "/backServlet");
          servletRegistrationBean.setLoadOnStartup(1);    //数字越小,启动优先级越高,但是必须大于0
          return servletRegistrationBean;
        }
      
      }

      但是不满足spring启动之后,spring不启动完成,就无法使用bean了,所fSOCLLtk以就按照前面的一种方法了

      总结

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

      0

      上一篇:

      下一篇:

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      最新开发

      开发排行榜