SSM框架如何在servlet的監聽器中使用Spring 容器的Bean

1、在java web項目中我們通常會有這樣的需求:
當項目啟動時執行一些初始化操作,例如從數據庫加載全局配置文件等,通常情況下我們會用JavaEE規范中的Listener去實現

public class ConfigListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
          //執行初始化操作
    }
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    }
}

2、這樣當servlet容器初始化完成后便會調用contextInitialized方法。但是通常我們在執行初始化的過程中會調用service和dao層提供的方法,而現在web項目通常會采用spring框架來管理和裝配bean,我們想當然會像下面這么寫,假設執行初始化的過程中需要調用ConfigService的initConfig方法,而ConfigService由spring容器管理(標有@Service注解)

public class ProductListener implements ServletContextListener {
 
    @Autowired
    private ProductService productService;
     
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        productService.queryAll();
    }
 
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    }
}

(1)Listener的生命周期是由servlet容器(例如tomcat)管理的,項目啟動時上例中的ConfigListener是由servlet容器實例化并調用其contextInitialized方法,而servlet容器并不認得@Autowired注解,因此導致ConfigService實例注入失敗。

(2)而spring容器中的bean的生命周期是由spring容器管理的。

4.那么該如何在spring容器外面獲取到spring容器bean實例的引用呢?這就需要用到spring為我們提供的WebApplicationContextUtils工具類,該工具類的作用是獲取到spring容器的引用,進而獲取到我們需要的bean實例。代碼如下

import java.util.List;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
 
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.Test.entity.Product;
import com.Test.service.productService;
 

/**
 * 監聽器實現定時任務
 * @author hph
 *
 */
public class OrderTimerRunnable implements ServletContextListener {
 
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
 
    }
 
    @Override
    public void contextInitialized(final ServletContextEvent sce) {
        TimerTask task=new TimerTask(){
            @Override  
            public void run() {  
                System.out.println("監聽器獲得spring容器的數據"); 
                ProductService productService = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext()).getBean(ProductService.class);
                List<Product> ordersList = productService.queryAll();
                System.out.println("數據打印--------------------------"+ordersList);             
                } 
    };
        Timer timer=new Timer();
        timer.scheduleAtFixedRate(task, 0, 5000);
    }
}

注意:以上代碼有一個前提,那就是servlet容器在實例化ConfigListener并調用其方法之前,要確保spring容器已經初始化完畢!而spring容器的初始化也是由Listener(ContextLoaderListener)完成,因此只需在web.xml中先配置初始化spring容器的Listener,然后在配置自己的Listener,配置如下

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
</context-param>
 
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
 
<listener>
    <listener-class>com.test.OrderTimerRunnable</listener-class>
</listener>
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。