1. 程式人生 > >Spring BeanFactory 和 ApplicationContext

Spring BeanFactory 和 ApplicationContext

Spring通過配置檔案描述了Bean和Bean之間的依賴關係,通過java反射例項化bean並建立彼此的依賴關係。除此之外還提供了Bean例項的快取,生命週期的管理,bean例項代理,時間釋出,資源裝載等

1 BeanFactory

1.1 簡介

屬於Spring的核心介面,提供了高階IOC的配置機制,BeanFactory是框架的基本設施,面向spring本身,BeanFactory在啟動容器時,並不會初始化配置檔案中定義的Bean,初始化發生在第一次呼叫,對於單例的Bean,BeanFactory會快取在Bean例項,所以在第二次使用時,直接從快取中獲取Bean例項

1.2 BeanFactory繼承體系


1.3 類簡介

1.3.1 BeanFactory

需要管理Bean的生命週期,初始化時需要實現如下介面

 * <ol>
 * <li>BeanNameAware's {@code setBeanName}
 * <li>BeanClassLoaderAware's {@code setBeanClassLoader}
 * <li>BeanFactoryAware's {@code setBeanFactory}
 * <li>EnvironmentAware's {@code setEnvironment}
 * <li>EmbeddedValueResolverAware's {@code setEmbeddedValueResolver}
 * <li>ResourceLoaderAware's {@code setResourceLoader}
 * (only applicable when running in an application context)
 * <li>ApplicationEventPublisherAware's {@code setApplicationEventPublisher}
 * (only applicable when running in an application context)
 * <li>MessageSourceAware's {@code setMessageSource}
 * (only applicable when running in an application context)
 * <li>ApplicationContextAware's {@code setApplicationContext}
 * (only applicable when running in an application context)
 * <li>ServletContextAware's {@code setServletContext}
 * (only applicable when running in a web application context)
 * <li>{@code postProcessBeforeInitialization} methods of BeanPostProcessors
 * <li>InitializingBean's {@code afterPropertiesSet}
 * <li>a custom init-method definition
 * <li>{@code postProcessAfterInitialization} methods of BeanPostProcessors
 * </ol>
 *
 * <p>On shutdown of a bean factory, the following lifecycle methods apply:
 * <ol>
 * <li>{@code postProcessBeforeDestruction} methods of DestructionAwareBeanPostProcessors
 * <li>DisposableBean's {@code destroy}
 * <li>a custom destroy-method definition
 * </ol>
public interface BeanFactory {
	///對FactoryBean轉義,因為如果使用bean的名字檢索FactoryBean得到的物件是工廠生成的物件
	String FACTORY_BEAN_PREFIX = "&";
	//通過名稱獲取bena例項
	Object getBean(String name) throws BeansException;
	//按照類象獲得Bean,requiredType可以是父類
	<T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
	//按照給定的引數建立bean例項(僅在建立新例項時才應用,而不是在檢索現有例項時應用)
	Object getBean(String name, Object... args) throws BeansException;
	//根據型別獲得Bean
	<T> T getBean(Class<T> requiredType) throws BeansException;
	//按照給定的引數建立對應的Bean(僅在建立新例項時才應用,而不是在檢索現有例項時應用)
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
	//根據name判斷,是否含有某個Bean
	boolean containsBean(String name);
	//是否單例Bean
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
	//是否為原型Bean
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
	//檢查bean是否和給定的型別匹配
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
	boolean isTypeMatch(String name, @Nullable Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
	//獲取Bean的Calss型別
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;
	//獲取Bean別名
	String[] getAliases(String name);

}

1.3.2 AutowireCapableBeanFactory 

提供自動裝配bean能力的功能支援,在BeanFactory基礎上實現對已存在例項的管理,預設實現AbstractAutowireCapableBeanFactory可以使用這個介面整合其它框架,捆綁並填充並不由Spring管理的已存在的例項,通過ApplicationContextgetAutowireCapableBeanFactory介面獲取.定義5種自動裝配策略:不注入AUTOWIRE_NO,使用bean name策略裝配AUTOWIRE_BY_NAME,使用型別裝配策略AUTOWIRE_BY_TYPE,使用構造器裝配策略AUTOWIRE_CONSTRUCTOR,自動裝配策略AUTOWIRE_AUTODETECT

1.3.3 HierarchicalBenFactory

父子級聯IOC容器介面,子容器可以訪問父容器中的Bean,但是父容器不能訪問子容器中的Bean,在同一個容器中Bean的id時唯一的,但在父子容器中子容器可以擁有一個和父容器id相同的Bean

public interface HierarchicalBeanFactory extends BeanFactory {

	/**
	 * Return the parent bean factory, or {@code null} if there is none.
	 */
	@Nullable
	BeanFactory getParentBeanFactory();

	/**
	 * Return whether the local bean factory contains a bean of the given name,
	 * ignoring beans defined in ancestor contexts.
	 * <p>This is an alternative to {@code containsBean}, ignoring a bean
	 * of the given name from an ancestor bean factory.
	 * @param name the name of the bean to query
	 * @return whether a bean with the given name is defined in the local factory
	 * @see BeanFactory#containsBean
	 */
	boolean containsLocalBean(String name);

}

1.3.4 ConfigurableBeanFactory

增強IOC容器的可定製性,定義了設定類裝載器,屬性編輯器,容器初始化後置處理器,定義的邊界很多,具體的需要檢視API

1.3.5 SingletonBeanRegistry

允許在執行期間向容器註冊單例項Bean

void registerSingleton(String beanName, Object singletonObject);

1.3.6 BeanDefinitionRegistry

配置檔案中每一個<bean>節點都可以通過一個BeanDefinition表示,該介面提供以編碼的形式向容器中註冊Bean,提供了刪除Bean的方法以及獲得BeanDefintion的方法

	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException;

	/**
	 * Remove the BeanDefinition for the given name.
	 * @param beanName the name of the bean instance to register
	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
	 */
	void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	/**
	 * Return the BeanDefinition for the given bean name.
	 * @param beanName name of the bean to find a definition for
	 * @return the BeanDefinition for the given name (never {@code null})
	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
	 */
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

1.3.7 ConfigurableListableBeanFactory

提供bean definition的解析,註冊功能,對單例Bean預載入(解決迴圈依賴問題).

1.3.7.1 設定忽略的依賴關係,註冊找到的特殊依賴

    void ignoreDependencyType(Class<?> type); // 忽略型別

    void ignoreDependencyInterface(Class<?> ifc); // 忽略介面

    void registerResolvableDependency(Class<?> dependencyType, Object autowiredValue);

    boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException;

1.3.7.2 獲取bean定義 (可以訪問屬性值跟構造方法的引數值)

    BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

1.3.7.3 鎖定配置資訊.在呼叫refresh時會使用到.

    void freezeConfiguration();

    boolean isConfigurationFrozen();

1.3.7.4 預載入不是懶載入的單例.用於解決迴圈依賴問題

    void preInstantiateSingletons() throws BeansException;

2 ApplicationContext

2.1 簡介

ApplicationContext是由BeanFactory派生而來的,主要的實現是ClassPathXmlApplicationContext ,FileSystemXmlApplicationContext,XmlWebApplicationContext。面向的是框架開發者,幾乎所有的應用都可以使用ApplicationContext而不是BeanFactory。ClassPathXmlApplicationContext預設從類路徑下載入配置檔案,FileSystemXmlApplicationContext預設從系統檔案中載入配置檔案。XmlWebApplicationContext預設從相對於Web根目錄下載入配置檔案ApplocationContext在初始化應用上下文容器時,會初始化所有單例Bean。

2.2 繼承體系

2.3 類簡介

2.3.1 ApplicationContext

訪問應用程式元件的Bean工廠方法。繼承自ListableBeanFactory,提供如下功能:1. 以通用的方式載入檔案資源的能力。2. 將事件釋出到註冊監聽器的功能。3. 解析訊息的能力,支援國際化。4. 從父上下文繼承

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

	省略部分程式碼
	//獲得父應用上下文容器
	ApplicationContext getParent();

	//獲得自動裝配Bean能力
	AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;

}

2.3.2 ApplicationEventPublisher

使容器具有釋出應用上下文事件的功能,包括容器的啟動,關閉事件等,凡是實現了ApplicationListener事件監聽介面的Bean都能夠接收到容器事件並對該事件進行處理。在ApplicationContext抽象實現類AbstractApplicationContext中存在ApplicationEventMulticaster負責儲存所有的監聽器並在事件發生時通知監聽器

public interface ApplicationEventPublisher {

	//通知該應用中註冊的匹配的事件監聽器,事件有可能是框架事件也有可能是特定的應用程式事件
	default void publishEvent(ApplicationEvent event) {
		publishEvent((Object) event);
	}
	//向監聽器通知事件
	void publishEvent(Object event);

}

2.3.3 MessageSource

為應用提供i18n國際化訊息訪問的功能

2.3.4 LifeCycle

主要提供了start() & stop()兩個方法,主要用於控制非同步處理過程,在具體使用時該介面需要同時被ApplicationContext和具體的Bean實現,ApplicationContext會將start/stop資訊傳遞給該容器中所有實現了該介面的Bean,達到控制和任務排程等目的

2.3.5 ConfigurableApplicationContext

擴充套件了ApplicationContext,主要新增了兩個方法refresh和close,讓容器具有重新整理,關閉應用上下文的能力。在應用上下文關閉的情況下,呼叫refresh可以啟動應用上下文,在已經啟動的情況下,呼叫refresh可以清除應用上下文的快取並重新載入配置資訊。close關閉應用上下文

	/**
	 * Load or refresh the persistent representation of the configuration,
	 * which might an XML file, properties file, or relational database schema.
	 * <p>As this is a startup method, it should destroy already created singletons
	 * if it fails, to avoid dangling resources. In other words, after invocation
	 * of that method, either all or no singletons at all should be instantiated.
	 * @throws BeansException if the bean factory could not be initialized
	 * @throws IllegalStateException if already initialized and multiple refresh
	 * attempts are not supported
	 */
	void refresh() throws BeansException, IllegalStateException;

	/**
	 * Close this application context, releasing all resources and locks that the
	 * implementation might hold. This includes destroying all cached singleton beans.
	 * <p>Note: Does <i>not</i> invoke {@code close} on a parent context;
	 * parent contexts have their own, independent lifecycle.
	 * <p>This method can be called multiple times without side effects: Subsequent
	 * {@code close} calls on an already closed context will be ignored.
	 */
	@Override
	void close();

3 BeanFactory & ApplicationContext

BeanFactory:面向的是Spring,屬於Spring的基礎設施,是Bean集合的工廠類,其中包含了各種Bean的定義,客戶端請求時將對應的Bean例項化,快取所有單例項的Bean。生成協作類之間的關鍵即解決類之間的依賴關係,還包含了Bean生命週期的控制,預設實現是DefalutListableBeanFactory。在首次使用Bean的時候會初始化Bean

ApplicationContext:面向的是Spring應用的,ApplicationContext擴充套件於BeanFactory,所以它具有BeanFactory所有的功能,除此之外ApplicationContext提供:1. 以通用的方式載入檔案資源的能力。2. 將事件釋出到註冊監聽器的功能。3. 解析訊息的能力,支援國際化。4. 從父上下文繼承的特性。在容器啟動時,會建立所有單例項的Bean。預設實現有ClassPathXmlAC,FileSystemXmlAC,WebXmlAC

4 WebApplicationContext

適用於Web應用,預設從相對於Web根目錄的路徑中載入配置檔案並完成初始化。WebApplicationContext中可以獲得ServletContext的引用。這個Web應用上下文作為屬性放在ServletContext中,一般web應用能夠訪問Spring應用上下文。可以通過WebApplicationContextUtils.getWebApplicationContext(ServletContext sc )從ServletContext中獲取Spring應用上下文(WebApplicationContext)

public interface WebApplicationContext extends ApplicationContext {

	/**
	 * Context attribute to bind root WebApplicationContext to on successful startup.
	 * <p>Note: If the startup of the root context fails, this attribute can contain
	 * an exception or error as value. Use WebApplicationContextUtils for convenient
	 * lookup of the root WebApplicationContext.
	 * @see org.springframework.web.context.support.WebApplicationContextUtils#getWebApplicationContext
	 * @see org.springframework.web.context.support.WebApplicationContextUtils#getRequiredWebApplicationContext
	 */
	String ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE = WebApplicationContext.class.getName() + ".ROOT";

	/**
	 * Scope identifier for request scope: "request".
	 * Supported in addition to the standard scopes "singleton" and "prototype".
	 */
	String SCOPE_REQUEST = "request";

	/**
	 * Scope identifier for session scope: "session".
	 * Supported in addition to the standard scopes "singleton" and "prototype".
	 */
	String SCOPE_SESSION = "session";

	/**
	 * Scope identifier for the global web application scope: "application".
	 * Supported in addition to the standard scopes "singleton" and "prototype".
	 */
	String SCOPE_APPLICATION = "application";

	/**
	 * Name of the ServletContext environment bean in the factory.
	 * @see javax.servlet.ServletContext
	 */
	String SERVLET_CONTEXT_BEAN_NAME = "servletContext";

	/**
	 * Name of the ServletContext/PortletContext init-params environment bean in the factory.
	 * <p>Note: Possibly merged with ServletConfig/PortletConfig parameters.
	 * ServletConfig parameters override ServletContext parameters of the same name.
	 * @see javax.servlet.ServletContext#getInitParameterNames()
	 * @see javax.servlet.ServletContext#getInitParameter(String)
	 * @see javax.servlet.ServletConfig#getInitParameterNames()
	 * @see javax.servlet.ServletConfig#getInitParameter(String)
	 */
	String CONTEXT_PARAMETERS_BEAN_NAME = "contextParameters";

	/**
	 * Name of the ServletContext/PortletContext attributes environment bean in the factory.
	 * @see javax.servlet.ServletContext#getAttributeNames()
	 * @see javax.servlet.ServletContext#getAttribute(String)
	 */
	String CONTEXT_ATTRIBUTES_BEAN_NAME = "contextAttributes";


	/**
	 * Return the standard Servlet API ServletContext for this application.
	 */
	@Nullable
	ServletContext getServletContext();

}

4.1 繼承體系

4.2 類簡介

4.1.1 ConfigurableWebApplicationContext

允許通過配置的方式例項化WebApplicationContext,提供了為Spring設定Web應用上下文以及設定Spring配置檔案地址的功能。配置檔案地址是相對於Web根目錄的地址

	/**
	 * Set the ServletContext for this web application context.
	 * <p>Does not cause an initialization of the context: refresh needs to be
	 * called after the setting of all configuration properties.
	 * @see #refresh()
	 */
	void setServletContext(@Nullable ServletContext servletContext);

	/**
	 * Set the config locations for this web application context in init-param style,
	 * i.e. with distinct locations separated by commas, semicolons or whitespace.
	 * <p>If not set, the implementation is supposed to use a default for the
	 * given namespace or the root web application context, as appropriate.
	 */
	void setConfigLocation(String configLocation);

	/**
	 * Set the config locations for this web application context.
	 * <p>If not set, the implementation is supposed to use a default for the
	 * given namespace or the root web application context, as appropriate.
	 */
	void setConfigLocations(String... configLocations);

4.3 Spring應用上下文和Web應用上下文的關係

WebApplicationContext 中定義了一個常量ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,在上下文啟動時,WebApplicationContext例項以此鍵存放在ServletContext的屬性列表中,可以通如下語句獲得WebApplicationContext。

servletContext.getAttribute(WebApplicationContext,ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE).它們的關係如下


4.4 Bean在WebApplicationContext中的範圍

之前Bean的範圍有兩個:singleton & prototype,在WebApplicationContext中新增了3個:request,session,global session

4.5 WebApplicationContext初始化

WebApplicationContext需要ServletContext例項,必須在擁有Web容器的前提下才能夠完成啟動工作。可以在web.xml中配置自啟動的servlet或者web容器監聽器,就可以完成spring web應用上下文的啟動。不管是哪種配置都需要使用日誌功能。

4.5.1 配置自啟動servlet

    <!—配置自啟動servlet—>
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderServlet</listener-class>  
    </listener>  

    <!—指定配置檔案路徑—>
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>/WEB-INF/applicationContext.xml,/WEB-INF/applicationContextd.xml</param-value>  
    </context-param> 

4.5.2 配置web容器監聽器

    <!—配置web容器監聽器—>
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>  

    <!—指定配置檔案路徑—>
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>classpath:spring/applicationContext.xml</param-value>  
    </context-param> 

相關推薦

Spring BeanFactory ApplicationContext

Spring通過配置檔案描述了Bean和Bean之間的依賴關係,通過java反射例項化bean並建立彼此的依賴關係。除此之外還提供了Bean例項的快取,生命週期的管理,bean例項代理,時間釋出,資源裝載等1 BeanFactory1.1 簡介屬於Spring的核心介面,提供

springBeanFactoryApplicationContext原始碼詳解(一)

轉自http://www.sandzhang.com/blog/2011/04/10/Spring-BeanFactory-ApplicationContext-Detail-1/ 版本:spring-framework-3.0.5.RELEASE Spring的最核心的部分就是BeanFactory了,

一,Spring容器BeanFactoryApplicationContext對比

BeanFactory和ApplicationContext對比 BeanFactory和ApplicationContext聯絡 BeanFactory和ApplicationContext是Spring的兩大核心介面,而其中Application

springBeanFactoryApplicationContext原始碼詳解(二)

轉自http://www.sandzhang.com/blog/2011/05/11/Spring-BeanFactory-ApplicationContext-Detail-2/ 版本:spring-framework-3.0.5.RELEASE 接上篇繼續 一、首先看ConfigurableBeanF

SpringBeanFactoryApplicationContext的生命週期及其區別詳解

Bean的生命週期 在很多技術中,都有生命週期這個概念,如在Android中,有Activity、Fragment等的生命週期;在Web容器中,有Servlet的生命週期。想要成為高階開發者,就必須要深入理解其生命週期。同樣的,在Spring容器中的Bean也

Spring學習筆記】1:開發環境,BeanFactoryApplicationContext兩類容器

開發環境 和Struts2,Hibernate一樣把下載的jar包放在WEB-INF/lib/下就可以了,最小依賴是: 其中commons-logging-*.jar是額外的,不是Spring自帶的。 BeanFactory容器 是為依賴注入(DI)

BeanFactoryApplicationContext有什麽區別?

文件讀取 資源文件 web應用 文本消息 ssp initial nco file 從表 BeanFactory 可以理解為含有bean集合的工廠類。BeanFactory 包含了種bean的定義,以便在接收到客戶端請求時將對應的bean實例化。BeanFactory還能在

beanFactoryApplicationContext的區別關係

beanFactory和ApplicationContext的區別和關係: ApplicationContext建立在BeanFactory的基礎之上,提供了更多面嚮應用的功能, 它提供了國際化支援和框架事件體系,但有下面幾點不同: 1)獲取beanFactory和Application

BeanFactoryApplicationContext聯絡區別

在Srping Ioc容器中,有BeanFactory和ApplicationContext兩個系列,分別是: 實現BeanFactory介面的簡單容器,具備最基本功能。 實現

spring BeanFactoryApplicatContext

spring容器 BeanFactory提供了IoC的功能;ApplicatContext建立在BeanFactory的基礎上 BeanFactory頂層介面 package org.springframework.beans.factory; import org.spri

12--Spring BeanFactoryFactoryBean的區別

上一篇介紹了Spring中bean的作用域和生命週期,今天繼續來溫習Spring中的另一個重要介面FactoryBean,在初學Spring時,大家可能混淆Spring中的兩個介面,FactoryBean和BeanFactory,我們先來看一下這兩者的各自

BeanFactory ApplicationContext(Bean工廠應用上下文)

一、BeanFactory 和ApplicationContext Bean 工廠(com.springframework.beans.factory.BeanFactory)是Spring 框架最核心的介面,它提供了高階IoC 的配置機制。 應用上下文(com.sprin

面試還不知道BeanFactoryApplicationContext的區別?

介面 BeanFactory 和 ApplicationContext 都是用來從容器中獲取 Spring beans 的,但是,他們二者有很大不同 我看到過很多問 BeanFactory 和 ApplicationContext 不同點的問題,考慮到這,我應該使用前者還是後者從 Spring 容器中獲取

java面試題:spring中的BeanFactoryApplicationContext的作用區別?

          2. ApplicationContext除了提供上述BeanFactory所能提供的功能之外,還提供了更完整的框架功能:                  a. 國際化支援                        b. 資源訪問:Resource rs = ctx. getR

spring中的BeanFactoryApplicationContext的作用區別?

BeanFactory類關係繼承圖 1. BeanFactory類結構體系: BeanFactory介面及其子類定義了Spring IoC容器體系結構,由於BeanFactory體系非常的龐大和複雜,因此要理解Spring IoC,需要先理清BeanFactory

Spring系列之beanFactoryApplicationContext

初始化 緩存 arc 等待 管理bean 核心 畫的 ssi alias 一、BeanFactoryBeanFactory 是 Spring 的“心臟”。它就是 Spring IoC 容器的真面目。Spring 使用 BeanFactory 來實例化、配置和管理 Bean。

Spring中的BeanFactoryFactoryBean的區別

get bject ins let 區別 inter on() iss exceptio 一句話介紹 BeanFactory接口用來生產Bean,它處理生產bean的接口體系的最頂層,getBean方法可以獲取bean。FactoryBean接口用來定制Bean的生產過程

Spring原始碼解析-applicationContext.xml載入bean的註冊

Spring原始碼解析-applicationContext.xml載入和bean的註冊 萬事開頭難,就要從頭開始 Spring初始化 Spring是如何找到applicationContext.xml檔案 將xml檔

Spring Bean的生命週期之我的理解(三)------BeanFactoryFactoryBean

前言 大家可能使用Spring框架已經很久了,但是對其中的一些概念可能會比較模糊,比如BeanFactory和FactoryBean,詐一看,兩個沒啥區別,仔細研究後發現,其實本質上是兩個不同的單元。 概念 BeanFactory 字面意思講就是

springBeanFactoryFactoryBean的區別

區別:BeanFactory是個Factory,也就是IOC容器或物件工廠,FactoryBean是個Bean。在Spring中,所有的Bean都是由BeanFactory(也就是IOC容器)來進行