Spring依賴注入servlet對談監聽器


Spring提供了一個 「ContextLoaderListener」 監聽器,以使 Spring 依賴注入到對談監聽器。 在本教學中,通過新增一個 Spring 依賴注入一個bean 到對談監聽器修改 HttpSessionListener 例子。

1. Spring Beans

建立一個簡單的計數服務來列印建立的對談總數。

File : CounterService.java

package com.tw511.common;
 
public class CounterService{
 
	public void printCounter(int count){
		System.out.println("Total session created : " + count);
	}

}

File : counter.xml – Bean組態檔案

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

	<bean id="counterService" class="com.tw511.common.CounterService" />
	
</beans>

2. WebApplicationContextUtils

使用「WebApplicationContextUtils」來獲得 Spring 上下文,以後可以得到任何宣告Spring的Bean 在一個正常的 Spring 方式。

File : SessionCounterListener.java

package com.tw511.common;
 
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
 
public class SessionCounterListener implements HttpSessionListener {
 
     private static int totalActiveSessions;
 
     public static int getTotalActiveSession(){
           return totalActiveSessions;
     }
 
    @Override
    public void sessionCreated(HttpSessionEvent arg0) {
           totalActiveSessions++;
           System.out.println("sessionCreated - add one session into counter");	
           printCounter(arg0);
    }
 
    @Override
    public void sessionDestroyed(HttpSessionEvent arg0) {
           totalActiveSessions--;
           System.out.println("sessionDestroyed - deduct one session from counter");	
           printCounter(arg0);
    }	
  
    private void printCounter(HttpSessionEvent sessionEvent){

          HttpSession session = sessionEvent.getSession();

          ApplicationContext ctx = 
                WebApplicationContextUtils.
                      getWebApplicationContext(session.getServletContext());

          CounterService counterService = 
                      (CounterService) ctx.getBean("counterService");

          counterService.printCounter(totalActiveSessions);
    }
}

3. 整合

唯一的問題是,如何使 Web 應用程式知道在哪裡可以載入 Spring bean 組態檔案?秘訣是在「web.xml」檔案中。
  1. 註冊「ContextLoaderListener」作為第一個監聽器,使Web應用程式知道Spring上下文載入程式。
  2. 組態「contextConfigLocation」,並定義Spring的bean組態檔案。

File : web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>
  
  <context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>/WEB-INF/Spring/counter.xml</param-value>
  </context-param>

  <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
  </listener>

  <listener>
	<listener-class>
            com.tw511.common.SessionCounterListener
        </listener-class>
  </listener>

  <servlet>
	<servlet-name>Spring DI Servlet Listener</servlet-name>
	<servlet-class>com.tw511.common.App</servlet-class>
  </servlet>
 
  <servlet-mapping>
	<servlet-name>Spring DI Servlet Listener</servlet-name>
	<url-pattern>/Demo</url-pattern>
  </servlet-mapping>
  
</web-app>

File : App.java

package com.tw511.common;
 
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
 
public class App extends HttpServlet{
 
  public void doGet(HttpServletRequest request, HttpServletResponse response)
        throws IOException{
		
        HttpSession session = request.getSession(); //sessionCreated() is executed
        session.setAttribute("url", "tw511.com"); 
        session.invalidate();  //sessionDestroyed() is executed
		  
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<body>");
        out.println("<h1>Spring Dependency Injection into Servlet Listenner</h1>");
        out.println("</body>");
        out.println("</html>");	
		
   }
} 

啟動Tomcat,並存取 URL 「http://localhost:8080/7.2-SpringDemo/"

輸出結果

sessionCreated - add one session into counter
Total session created : 1
sessionDestroyed - deduct one session from counter
Total session created : 0
看看控制台的輸出,會得到通過 Spring DI 記數服務的 bean,並列印對談的總數。

總結

在Spring中,「ContextLoaderListener」是一個通用的方法整合Spring依賴注入到幾乎所有的Web應用程式。

下載程式碼 –  http://pan.baidu.com/s/1bpmhQY