Spring獲取Bean 原始碼淺析
今天開門見山,直接亮程式碼~
MyTestBean bean = (MyTestBean)bf.getBean("myTestBean")
我想上面這行程式碼,第一次接觸過spring這個框架時都應該接觸過;讀取xml中我們配置的bean;
spring分為7大部分組成,有一個部分叫做:SpringBean;
為了知道這句程式碼實現了什麼樣的功能,看官可以可以開啟你的開發工具,找到下面這張圖的幾個包;
首先開啟AbstractBeanFactory 這個類, 找到 getBean 這個方法:
進入doGetBean :public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }
@SuppressWarnings("unchecked") protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { //把beanName 前面可能存在的 所有符號 全部取出; final String beanName = transformedBeanName(name); Object bean; /** * spring會先檢查快取中或者例項工廠中是否有對應的例項,因為在建立單例bean的時候回存在醫療注入的情況; * 而在建立以來的時候為了避免迴圈依賴,spring建立bean的原則是不等bean建立完成就會將建立bean的 objectfactory提前曝光, * 也就是將objectFactory加入到快取中,一旦下一個bean建立的時候需要依賴上個bean則直接使用objectfactory; */ Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isDebugEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.debug("Returning cached instance of singleton bean '" + beanName + "'"); } } bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); }
迴圈依賴是什麼意思呢? 如果存在 A中有B的屬性,B中又有A的屬性,那麼當依賴注入的時候,就會產生A還未完成建立的時候又去建立B,又再次返回建立A;
進入 getSingleton(beanName) 方法 會跳到 DefaultSingletonBeanRegistry 這個類的
再次進入 getSingleton(beanName, true )這個方法;
進入這個方法之前,先了解一個概念,單例在spring的同一個容器中只會被建立一個,之後獲取bean就可以直接衝單例的快取中獲取了;
下面介紹的就是從快取中獲取bean的情況;
這樣就返回了單例的 singletonObject
看到這裡,你可能不知道 singletonFactory怎麼來的, 進入 singletonFactories 這個 引用去看看:
/** Cache of singleton objects: bean name --> bean instance */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
/** Cache of singleton factories: bean name --> ObjectFactory */
private final Map<String, ObjectFactory> singletonFactories = new HashMap<String, ObjectFactory>(16);
/** Cache of early singleton objects: bean name --> bean instance */
private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
/** Set of registered singletons, containing the bean names in registration order */
private final Set<String> registeredSingletons = new LinkedHashSet<String>(64);
1.singletonObjects : 用於儲存beanName和建立bean例項之間的關係
2.singletonFactories : 用於儲存beanName和建立bean的工廠之間的關係
3.earlySingletonObjects :也是儲存beanName和bean例項之間的關係,與singletonObjects 的不同之處在於,當一個單例bean被放在這裡後,那麼當bean還在建立過程中,就可以通過getBean的方法獲取了,其目的是用來檢測迴圈引用。
4.registeredSingletons : 用於儲存當前所有已註冊的bean。
因為 singletonFactory實現了 ObjectFactory這個介面; spring全家桶 會根據 beanName去建立 一個singletonFactory;
上面是從緩衝中獲取單例,那麼緩衝中要是不存在已經載入好的單例bean,那就要重頭開始執行載入bean了,spring重寫了getSingleton,
public Object getSingleton ( String beanName, ObjectFactory singletonFactory) { ...... }
從上面程式碼可以看到,spring依賴注入時,使用了雙重判斷加鎖的單例模式,首先從快取中獲取bean例項,如果為null,對快取map加鎖,然後再從快取中獲取bean,如果繼續為null,就建立一個bean。這樣雙重判斷,能夠避免在加鎖的瞬間,有其他依賴注入引發bean例項的建立,從而造成重複建立的結果。
Spring並沒有使用我們常見的私有構造方法來建立bean,而是通過singletonFactory.getObject()返回具體beanName對應的ObjectFactory來建立bean。
這就是spring獲取bean的一個簡單流程;建立了spring的bean物件,還沒完,還沒有例項化這個bean。 且聽下回分解~
相關推薦
Spring獲取Bean 原始碼淺析
今天開門見山,直接亮程式碼~ MyTestBean bean = (MyTestBean)bf.getBean("myTestBean")我想上面這行程式碼,第一次接觸過spring這個框架時都應該接觸過;讀取xml中我們配置的bean; spring分為7大部分組成,
IOC容器從BeanFactory獲取Bean原始碼淺析
我們經常說IOC容器,它具體由誰來充當這個角色呢,我的理解ApplicationContext是用來管理IOC容器中的Bean的,IOC容器本質上是由DefaultListableBeanFactory擔當的。我們想從容器中獲得某個Bean,是通過ApplicationCon
Spring獲取bean的一種方式
ext bean 使用 set implement tex spring ati ride 隨便一百度,網上一大把,並且還不止一種。所以這裏就只記錄目前用的一種好了。 實現ApplicationContextAware接口 即可: import org.springfra
Spring 獲取bean 幾種方式
讀取 獲取 static ava ade beans java ride .html 轉載自: http://www.cnblogs.com/luoluoshidafu/p/5659574.html 1.讀取xml文件的方式,這種在初學入門的時候比較適用 。 A
spring 獲取bean幾種方式
這種方式適合於採用Spring框架的B/S系統,通過ServletContext物件獲取ApplicationContext物件,然後在通過它獲取需要的類例項。 這個類提供了方便的功能,這樣你就不必去記 ServletContext 中屬性的名字。 它的getWebApplicationContext()
Spring獲取bean幾種方式
方法四:繼承自抽象類WebApplicationObjectSupport 說明:類似上面方法,呼叫getWebApplicationContext()獲取WebApplicationContext 方法五:實現介面ApplicationContextAware 說明:實現該介面的setAppl
spring獲取bean例項(七)
Spring中獲取bean物件例項(七) 今天進行下面重要分析,從上一章我們可以得知,getSingleton最終的獲取物件還是呼叫createBean方法 sharedInstance = getSingleton(beanName, () -> { try
Spring獲取bean的三種方式
Demo 類程式碼: springbean xml 配置程式碼: 測試類程式碼: spring 獲取bean 第一種方法 BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("s
spring獲取bean的幾種方式
使用jdk:1.8、maven:3.3.3 spring獲取Bean的方式 pom.xml檔案內容: <?xml v
Spring原始碼:從FactoryBean獲取Bean的例項
主程式碼 詳細分析 主程式碼 類AbstractBeanFactory protected <T> T doGetBean(......){
static關鍵字,引發的spring普通類獲取spring的bean的思考
pan conf ati ets 普通 blog 編譯器 自定義 這也 在c++和java中static關鍵字用於修飾靜態成員變量和成員函數 舉例一個普通的javabean class AA { int a; static int b; geta/set
Spring在代碼中獲取bean的幾種方式(轉)
mxml get text spa 回調 獲取對象 ati -s null 獲取spring中bean的方式總結: 方法一:在初始化時保存ApplicationContext對象 1 ApplicationContext ac = new FileSystemXml
Spring Boot 獲取Bean對象實體
oid cep clas ride ext @override pub tex creat 一、實現 ApplicationContextAware 接口 package com.zxguan; import org.springframework.beans.Bean
spring的bean週期中BeanPostProcessor淺析
參考:https://www.cnblogs.com/sishang/p/6576665.html 1. 基本概念 spring容器在例項化bean之後(通過構造器建立物件並注入屬性值即為例項化),可以使用BeanPostProcessor介面在bean的初始化方法前後根據需要做自己的邏
Spring(4) Bean獲取Spring容器
當一個bean需要獲取它所在spring容器的時候,實際上這種情況是很常見的,例如要輸出國際化資訊,釋出事件等。 bean可以通過實現BeanFactoryAware介面實現獲取它所在的spring容器,BeanFactoryAware只有一個setBeanFactory方法,sprin
Spring 中 bean 註冊的原始碼解析
前言 所謂 bean 的註冊,就是把在配置檔案中配置的 <bean> 節點載入配記憶體中,供後續使用。 bean的註冊主要分為兩個階段,一個是準備階段,就是對配置檔案進行解析,把配置檔案載入到記憶體中,以 Document 的形式存放;第二個階段是對 Document 進行操作,獲取其中的節
Spring事務實現原始碼之事務實現以及Connection的繫結與獲取
PlatformTransactionManager是spring事務的高階抽象,事務的實現需要藉助PlatformTransactionManager完成,該管理主要方法如下: 當我們在使用事務的時候,需要呼叫如下方法獲取一個事務狀態物件。 TransactionS
Spring載入bean定義流程原始碼解析
在本文中,先對Spring載入和建立bean例項的流程跟著原始碼走一遍,在後續的文章中再對所涉及的類的其他方法具體介紹。 //這一步是載入指定的配置檔案 Resource resource = new ClassPathResource("bean.xm
spring 根據beanName獲取bean物件,呼叫其方法
通用類 @Component public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationConte
[轉]結合原始碼淺析Struts2與Spring整合的原理
文章的結構如下: 一、回顧Struts2與Spring整合的配置方法 二、(重點)對關鍵配置的分析 -------------------------------------------------------- 一、回顧Struts2與Spring整合的配置