web項目中獲取spring的bean對象

 Spring是一個輕量級的控制反轉(IoC)和麪向切面(AOP)的容器框架,如何在程序中不經過註解的形式(@Resource、@Autowired)獲取Spring配置的bean呢?java

   Bean工廠(com.springframework.beans.factory.BeanFactory)是Spring框架最核心的接口,它提供了高級IoC的配置機制。BeanFactory使管理不一樣類型的Java對象成爲可能,應用上下文(com.springframework.context.ApplicationContext)創建在BeanFactory基礎之上,提供了更多面嚮應用的功能,它提供了國際化支持和框架事件體系,更易於建立實際應用。咱們通常稱BeanFactory爲IoC容器,而稱ApplicationContext爲應用上下文。但有時爲了行文方便,咱們也將ApplicationContext稱爲Spring容器。
   對於二者的用途,咱們能夠進行簡單劃分:BeanFactory是Spring框架的基礎設施,面向Spring自己;ApplicationContext面向使用Spring框架的開發者,幾乎全部的應用場合咱們都直接使用ApplicationContext而非底層的BeanFactory。web

工廠方式:spring

Resource resource = new ClassPathResource("applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(resource);
factory.getBean(strName);

ApplicationContext的初始化和BeanFactory有一個重大的區別:BeanFactory在初始化容器時,並未實例化Bean,直到第一次訪問某個Bean時才實例目標Bean;而ApplicationContext則在初始化應用上下文時就實例化全部單實例的Bean。所以ApplicationContext的初始化時間會比BeanFactory稍長一些緩存

    附加信息,簡要說明Spring何時實例化bean,首先要分2種狀況
  第一:若是你使用BeanFactory做爲Spring Bean的工廠類,則全部的bean都是在第一次使用該Bean的時候實例化
  第二:若是你使用ApplicationContext做爲Spring Bean的工廠類,則又分爲如下幾種狀況:
       (1):若是bean的scope是singleton的,而且lazy-init爲false(默認是false,因此能夠不用設置),則 ApplicationContext啓動的時候就實例化該Bean,而且將實例化的Bean放在一個map結構的緩存中,下次再使用該Bean的時候, 直接從這個緩存中取
       (2):若是bean的scope是singleton的,而且lazy-init爲true,則該Bean的實例化是在第一次使用該Bean的時候進行實例化
       (3):若是bean的scope是prototype的,則該Bean的實例化是在第一次使用該Bean的時候進行實例化mybatis

要獲取XML中配置的Bean,最關鍵的是獲取org.springframework.context.ApplicationContextapp

方法一:獲取ApplicationContext的方法(多用於java工程)

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

或:框架

ApplicationContext context = new FileSystemXmlApplicationContext("D:/Workspaces/MyEclipse Professional 2014/dubbo-customer/src/main/resources/applicationContext.xml" );

這種方式實例化applicationContext是很是耗時的,這種方式適用於採用Spring框架的獨立應用程序,僅僅推薦使用在程序須要經過配置文件手工初始化Spring的狀況。
   ApplicationContext的主要實現類是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者默認從類路徑加載配置文件,後者默認從文件系統中裝載配置文件。ide

方法二:獲取ApplicationContext的方法(多用於web項目)

經過Spring提供的工具類獲取ApplicationContext對象,專爲web工程定製的方法,推薦Web項目中使用。例如:工具

ServletContext sc = request.getSession().getServletContext(); 
ApplicationContext ac1 = WebApplicationContextUtils  .getRequiredWebApplicationContext(sc)   
ApplicationContext ac2 = WebApplicationContextUtils  .getWebApplicationContext(sc)  
ac1.getBean("beanId");  
ac2.getBean("beanId");

其中,獲取ServletContext對象時的request.getSession().getServletContext()能夠改爲this.getServletContext()。ui

   注意:當使用WebApplicationContextUtils獲取ApplicationContext實例時,須要在web.xml配置文件中添加org.springframework.web.context.ContextLoaderListener監聽器,不然獲取不到ApplicationContext對象,返回Null。

  web.xml配置:

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

方法三:繼承自抽象類ApplicationObjectSupport

說明:抽象類ApplicationObjectSupport提供getApplicationContext()方法,能夠方便的獲取到ApplicationContext。
Spring初始化時,會經過該抽象類的setApplicationContext(ApplicationContext context)方法將ApplicationContext 對象注入。

方法四:繼承自抽象類WebApplicationObjectSupport 

經過繼承org.springframework.web.context.support.WebApplicationObjectSupport使用getWebApplicationContext() 獲取到org.springframework.web.context.WebApplicationContext
   因爲Web應用比通常的應用擁有更多的特性,所以WebApplicationContext擴展了ApplicationContext。WebApplicationContext定義了一個常量ROOT_WEB_APPLICATION_ CONTEXT_ATTRIBUTE,在上下文啓動時,WebApplicationContext實例即以此爲鍵放置在ServletContext的屬性列表中,所以咱們能夠在java類中直接經過如下語句從Web容器中獲取WebApplicationContext:

ServletContext sc = this.getServletContext();
WebApplicationContext wac = (WebApplicationContext)sc.getAttribute(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
DemoService demoService = (DemoService)wac.getBean("demoService");

方法五:實現接口ApplicationContextAware(推薦)

實現該接口的setApplicationContext(ApplicationContext context)方法,並保存ApplicationContext 對象。Spring初始化時,會經過該方法將ApplicationContext 對象注入。

package com.test.smsweb.context;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class AppContext implements ApplicationContextAware {

	private static ApplicationContext applicationContext;

	/**
	 * 當繼承了ApplicationContextAware類以後,那麼程序在調用 getBean(String)的時候會自動調用該方法,不用本身操做
	 */
	@Override
	public void setApplicationContext(org.springframework.context.ApplicationContext applicationContext)
			throws BeansException {
		this.applicationContext = applicationContext;
	}

	public Object getBean(String beanName) {
		return this.applicationContext.getBean(beanName);
	}
}

須要在配置文件中注入該類的bean

<bean id="appContext" name="appContext"
    	class="com.test.smsweb.context.AppContext">
</bean>

而後在java類中獲取spring的bean

AppContext appContext = new AppContext();
UserService userService = (UserService) appContext.getBean("userService");

------------------

package smsweb;

import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.test.smsweb.context.AppContext;
import com.test.smsweb.services.UserService;

public class AppContextTest {
	
	@Before
	public void setUp() {
		//使用"spring.xml"和"spring-mybatis.xml"這兩個配置文件建立Spring上下文
		ApplicationContext ac = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml","spring-mybatis.xml"});
	
	}
	
	@Test
	public void testAppContext() {
		System.out.println("-------------");
		AppContext appContext = new AppContext();
		UserService userService = (UserService) appContext.getBean("userService");
		System.out.println(userService.getById(1).getUsername());
	}

}
相關文章
相關標籤/搜索