Spring/SpringMVC在啟動完成后執行方法


在某些情況下,有可能你會有這種需求:在Spring/SpringMVC項目中,當Spring/SpringMVC啟動完成后,你需要執行一個方法來完成某些事件(比如創建網站地圖,比如從訂閱Redis服務器等),這個時候,可以使用Tomcat/Servlet容器提供的事件回調機制來完成,但是這樣有個問題是:無法使用Spring提供的Annotation,解決方法是:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.storezhang.web;

import com.storezhang.util.TimeUtils;
import com.storezhang.video.util.SiteMapUtils;
import java.util.Timer;
import java.util.TimerTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;

/**
 * 啟動監聽器
 *
 * @author Storezhang
 */
@Service
public class StartupListener implements ApplicationListener<ContextRefreshedEvent> {

    @Autowired
    private SiteMapUtils sites;

    @Override
    public void onApplicationEvent(ContextRefreshedEvent evt) {
        if (evt.getApplicationContext().getParent() == null) {
            createSitemap();
        }
    }

    private void createSitemap() {
        Timer timer = new Timer("createSitemap", true);
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                System.out.println("--->Create sitemap...");
                sites.createSiteMap();
                System.out.println("--->Success create sitemap...");
            }
        }, 1 * TimeUtils.MIN);
    }
}

 后續研究: 
applicationontext和使用MVC之后的webApplicationontext會兩次調用上面的方法,如何區分這個兩種容器呢? 

但是這個時候,會存在一個問題,在web 項目中(spring mvc),系統會存在兩個容器,一個是root application context ,另一個就是我們自己的 projectName-servlet context(作為root application context的子容器)。 

這種情況下,就會造成onApplicationEvent方法被執行兩次。為了避免上面提到的問題,我們可以只在root application context初始化完成后調用邏輯代碼,其他的容器的初始化完成,則不做任何處理,修改后代碼 

如下: 

    @Override  
      public void onApplicationEvent(ContextRefreshedEvent event) {  
        if(event.getApplicationContext().getParent() == null){//root application context 沒有parent,他就是老大.  
             //需要執行的邏輯代碼,當spring容器初始化完成后就會執行該方法。  
        }  
      }  


免責聲明!

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



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