spring容器加載完成之后進行開啟一個線程進行數據更新操作


原文:https://blog.csdn.net/wumanxin2018/article/details/80367948

 

最近在公司做項目時遇到一個問題,需要在Spring框架啟動后啟動一個線程接受別的系統發來的消息。因為這個線程里還需要處理自己的業務邏輯,所以會用到別的bean。 查找資料后又如下幾種方式可以實現。

1. 使用Spring的InitializingBean 接口來實現

package com.irisian.picturelabel.listener;

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();
logger.error(e.getMessage());
}
}
}).start();


}
}


2.開始還嘗試過servlet的方法,如

package com.irisian.picturelabel.servlet;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import 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;
    }

}


3.嘗試用listener方式是比較常用的。實際上,servelet API 提供了大量監聽器來監聽web應用的內部事件,從而允許當web應用內部事件發生時而回調監聽器的方法,常見的事件有:web應用被啟動、web應用被停止、用session開始、用戶session結束、用戶請求到達等。

其中ServletContextListener用於web應用的啟動和關閉。對於我們剛剛提及的需求,我們需要在web應用啟動的時候就開始啟動后台的服務線程。

    ServletContextListener有兩個常用的方法:

    void contextInitialized(ServletContextEvent sce)

    這個方法在Container初始化整個Web應用時調用,運行在該Web應用中servlet和filter初始化之前

    void contextDestroyed(ServletContextEvent sce)

    這個方法在Container卸載整個Web應用時調用,運行在該Web應用中servlet和filter的destroy()方法之后

例子:

    首先定義一個后台的服務線程

public class run implements Runnable{

 @Override
 public void run() {
  while(true){
   try {
       Thread.sleep(5000);
   } catch (InterruptedException e) {
    e.printStackTrace();
   }
    System.out.println("you mother call you to go home to eat......")
  }

 }

}

    定義一個listener類

package com.cims; 
 
import javax.servlet.ServletContextEvent; 
import javax.servlet.ServletContextListener; 
 
 
public class MyListener implements ServletContextListener {  
    public void contextDestroyed(ServletContextEvent e) {   
    } 
 
    public void contextInitialized(ServletContextEvent e) {  
            System.out.println("------------web start-------");

            new Thread(new run()).start();

    } 

最后需要在web.xml進行一下配置:

Web應用啟動時,后台自動啟動一個線程
啟動項目,會輸出你想要的內容。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM