1. 程式人生 > >獲取Spring上下文(ApplicationContext)的三種方法

獲取Spring上下文(ApplicationContext)的三種方法

 以前在專案中經常用到Spring上下文(ApplicationContext),每次使用都是百度一下,使用過就忘了。今天良心發現,寫一篇部落格,讓這個知識真正屬於我,也希望我寫的博文,可以幫助需要的人。

       Spring上下文(ApplicationContext)的獲取有三種方式。

   1.通過WebApplicationUtils工具類獲取。WebApplicationUtils類是在Spring框架基礎包spring-web-3.2.0. RELEASE.jar(我使用的是3.2.0版的jar包,大家可以去spring官網下載最新版的jar)中的類。使用該方法的必須依賴Servlet容器。

 使用方法如下: 

ApplicationContext ap =WebApplicationUtils.getWebApplicationContext(servletContextParam)

     其中servletContextParam是你需要傳入的Servlet容器引數。

     2. 通過ClassPathXmlApplicationContext類獲取。ClassPathXmlApplicationContext 類是在Spring框架基礎包spring-context-3.2.0. RELEASE.jar(我使用的是3.2.0版的jar包,大家可以去spring官網下載最新版的jar)中的類。

使用方法如下:

ApplicationContext ap = new ClassPathXmlApplicationContext("applicationContext.xml");

     其中applicationContext.xml檔案放在src下面,這樣就保證可以讀取到該檔案。這個XML的作用是集中配置和管理所有Bean。

    applicationContext.xml程式碼: 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
        //中間部分是你自己配置的所有bean
</beans>

  3.建立一個自己的工具類(SpringContextHolder)實現Spring的ApplicationContextAware介面。最後在Spring配置檔案中註冊你的工具類。配置如下:

<bean id="springContextHolder" class="com.fubo.utils.spring.SpringContextHolder" lazy-init="false"/>

   SpringContextHolder實現程式碼如下:

package com.fubo.utils.spring;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
/**
 * 實現對spring context 的管理
 * @author FB
 * @2017年3月29日
 * @上午9:07:27
 * @
 */
public class SpringContextHolder implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    /**
     * 實現ApplicationContextAware介面的context注入函式, 將其存入靜態變數.
     */
    public void setApplicationContext(ApplicationContext applicationContext) {
	SpringContextHolder.applicationContext = applicationContext; // NOSONAR
    }

    /**
     * 取得儲存在靜態變數中的ApplicationContext.
     */
    public static ApplicationContext getApplicationContext() {
	checkApplicationContext();
	return applicationContext;
    }

    /**
     * 從靜態變數ApplicationContext中取得Bean, 自動轉型為所賦值物件的型別.
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name) {
	checkApplicationContext();
	return (T) applicationContext.getBean(name);
    }

    /**
     * 從靜態變數ApplicationContext中取得Bean, 自動轉型為所賦值物件的型別.
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(Class<T> clazz) {
	checkApplicationContext();
	return (T) applicationContext.getBeansOfType(clazz);
    }

    /**
     * 清除applicationContext靜態變數.
     */
    public static void cleanApplicationContext() {
	applicationContext = null;
    }

    private static void checkApplicationContext() {
	if (applicationContext == null) {
	    throw new IllegalStateException(
		    "applicaitonContext未注入,請在applicationContext.xml中定義SpringContextHolder");
	}
    }
    
    
    public static void setHttpRequestResponseHolder(HttpServletRequest request, HttpServletResponse response){
        responseThreadLocal.set(response);
        ApplicationContext ap = WebApplicationContextUtils.getWebApplicationContext(null);
    }
    public static HttpServletResponse getHttpResponse(){
       return responseThreadLocal.get();
    }

    public static void clean(){
        responseThreadLocal.remove();
    }

    private static final ThreadLocal<HttpServletResponse> responseThreadLocal = new ThreadLocal();

    
   }
總結:方式1要依賴Servlet容器,方式2實際只適合測試使用,方式1,2都有明顯弊端。建議使用方式3。