第二步,obtainFreshBeanFactory() ,設置 BeanFactory 的 serializationId 後返回設計模式
第三步,prepareBeanFactory(beanFactory) ,作進一步的 BeanFactory 的準備工做,主要是爲其增長 BeanClassLoader、BeanExpressionResolver、PropertyEditorRegistrar、BeanPostProcessor(BeanPostProcessor,ApplicationListenerDetector)等操做,之因此有這一步是由於後續的 Bean 的實例化之後 DI 的相關操做等會依賴這些類提供的操做;能夠理解是爲其設置了一系列的靜態代理,在 Bean 的實例化的過程當中某些操做就須要經過這些代理去完成app
BeanFactoryProcessor 涉及到的內容也比較多,會單獨寫一篇文章來介紹用法和分析源碼,這裏簡單介紹一下框架
首先調用 postProcessBeanFactory(beanFactory); 這是一個留給子類實現的方法,此處沒有作任何邏輯而後調用 invokeBeanFactoryPostProcessors(beanFactory); 這裏註釋是調用已經註冊在上下文中的 BeanFactoryPostProcessor;實際上就算沒有註冊過的,它也會從 BeanFactory 中的 BeanDefinitionNames 中獲取對應的 BeanFactoryProcessor,而後調用 beanFactory.getBean 方法將其實例化。他主要作什麼工做呢,我舉個例子咱們使用 Spring 的時候有時候是基於 JavaConfig 的,會在某個類上面配置 @ComponentScan("com.xx.xxx"),這種在最初加載 BeanDefinition 的時候不會去解析 @ComponentScan("com.xx.xxx"),會在這個方法中解析該註解而且掃描對應路徑將其下的 BeanDefinition 轉入 BeanFactory 中。源碼分析
而後調用 registerBeanPostProcessors(beanFactory); 該方法會去 BeanFactory 中的 BeanDefinitions 中獲取 BeanPostProcessor 的實現類的 BeanDefinition 而後調用 getBean 方法將其實例化,而後將他們進行排序後註冊到 BeanFactory 的 beanPostProcessors 中。至關於就是提早一步將其實列化爲對象,以便於爲後續實列化對象這個過程服務。post
BeanPostProcessor 有不少的實現的子類,它們分別穿插於實例化 Bean 邏輯的各個地方,能夠極其靈活的調整實列化方式,和增長代理,修改 Bean 等功能;好比能夠在 Bean 實例化前檢查時候註冊有 InstantiationAwareBeanPostProcessor 該實現能夠提早返回代理對象,若是返回了,那麼後續的實例化操做就不會在進行;好比 MergedBeanDefinitionPostProcessor 他能夠在建立了早期 Bean 對象(後面會將上面是早期 Bean 對象)以後去合併 BeanDefinition 的內容,此次修改能夠影響到後續給早期 Bean 注入屬性值等內容等等設計
第二步, getObjectForBeanInstance 意思就是返回的 Bean 實例多是個 FactoryBean 也多是個普通 Bean 實例,那麼就封裝個方法普通 Bean 直接返回,FactoryBean 就調用其 getObject 方法來返回 Bean 實例(這裏和本文都只是描述主要內容,還有一些其它邏輯本身看源碼吧)3d
第二步,若是在當前 BeanFactory 中沒有找到該 BeanName 對應的 BeanDefinition 就遞歸的尋找父工廠,直到找到爲止代理
第二步,調用 resolveBeforeInstantiation 給 BeanPostProcessor 一個返回代理對象的機會,若是返回了的話,就不在走後續的實列化,初始化等流程了,這個方法的核心邏輯以下 cdn
好比咱們自定義了一個實現類以下 此時對 c 這個類的實列化的後續流程將不在執行,此處直接返回該代理對象,而後會調用 applyBeanPostProcessorsAfterInitialization 直接初始化的後續邏輯 通常來講若是沒有特殊設置這裏是沒有返回代理對象的,將會繼續執行後續步驟 第一步,調用 createBeanInstance 建立 BeanWrapper,一個 Bean 的包裝類,此處點擊去看發現通常狀況下就是走的反射建立,構造器.newInstance(args) 來建立該對象而且對其進行包裝後返回第二步,獲取到 BeanWrapper 中的 早期 Bean 實例,之因此說是早期是由於它仍是一個不完整的實列還未經歷初始化和屬性注入等相關操做對象
第三步,執行 MergedBeanDefinitionPostProcessor 的一些操做合併 BeanDefinition 的信息若是須要的話
這裏調用 addSingletonFactory 就是解決循環依賴問題的第二個關鍵步驟,分別將其添加到 singletonFactories 和 registeredSingletons 中,咱們在來配合這 doGetBean 中調用 getSingleton 方法來看 首先 singletonFactories 中獲取到 ObjectFactory 而後調用其 getObject 方法後放入 earlySingletonObjects 中而且返回,在調用 getObject 的時候實際上是調用的 getEarlyBeanReference(beanName, mbd, bean) 這個方法 可以看到這裏又有 BeanPostProcessor 的操做,主要作的邏輯就是在返回 Bean 實例前又留給用戶能夠調整早期 Bean 實例的機會到這一步早期的 Bean 實例就建立完成了,後面就是該填充 Bean 的屬性和執行初始化方法了。目前能夠看到 BeanPostProcessor 穿插在實例實例化的各個地方,極盡量的給框架提供更增強大的拓展性,後面的邏輯還會再次接觸到 BeanPostProcessor
早期 Bean 的實列化的流程,首先進行 BeanFactory 的準備工做包括設置 ClassLoader 設置基礎 BeanPostProcessor 初始化佔位符對應的值設置 BeanFactory 的工做狀態等待。而後調用 BeanFactoryPostProcessor 給容器一次再調整容器中的 BeanDefinitions 的機會(好比說將 @ComponentScan("com.xxx")路徑下的註解類掃描裝載爲 BeanDefinition 到容器中和調用咱們自定義的一些 BeanFactoryProcessor 等)。隨後根據 BeanDefinition 取出 Class 而後經過反射進行實例化一個早期的 Bean 實例,固然在以前還有一個調用 BeanPostProcessor 存在一個返回代理對象的機會若是返回就不進行後續的邏輯。最後將早期 Bean 實例構建爲 ObjectFactory 放入 singletonFactories 中結合 getSingleton 方法完美的解決了單例的循環依賴問題,因爲是一個 ObjectFactory 在調用 getObject 的時候會調用 getEarlyBeanReference 方法其中會檢測若是有 BeanPostProcessor(SmartInstantiationAwareBeanPostProcessor) 的話會調用該實現來覆蓋當前的早期 Bean 對象
根據目前幾章的源碼分析可以看到,Spring 利用了各類設計模式和鉤子方法和 BeanFactoryProcessor 和 BeanPostProcessor 使得其及其靈活,利用這些咱們可以很容易的定製第三方框架功能。目前運用了代理模式、委派模式、魔板方法模式、策略模式、工廠模式等等,後面會單獨寫一篇文章來聊聊 Spring 中的這些設計模式