Spring中Bean的生命週期以及IOC與AOP加載過程

首先說一下Bean的生命週期

Bean的生命週期

創建Bean >> 初始化 >> 摧毀

1.創建Bean

  當設置Bean爲單例時,在spring容器啓動時會創建Bean。

  當設置Bean爲多例是,在調用Bean時纔會被創建。

2.初始化

  使用init()來完成Bean的初始化操作,在初始化環節中,可以使用BeanPostProcesser(後置處理器),對Bean進行一系列的操作。

3.摧毀

  destroy()

  單例模式下,在容器關閉時會調用destroy()進行摧毀。

  多例模式下,bean不會被摧毀,也不會調用destroy方法。

 

 


IOC加載過程

spring啓動時會進入

註解AnnotationConfigApplicationContext()方法

AnnotationConfigApplicationContext()方法中

首先調用this()方法,初始化讀取器和掃描器

然後調用register(),註冊bean配置類

XML配置ClassPathXmlApplicationContext()方法

ClassPathXmlApplicationContext()方法中

super(parent)

setConfigLocations(configLocations)

無論是哪種方式最後都會進入refresh()方法,也是Spring初始化過程的重點

進入refresh方法

方法內使用synchronized鎖即將要操作的代碼塊進行加鎖,保證不會被重複初始化,此時的鎖的對象是一個final修飾的Object對象

進到同步代碼塊內有十幾個方法(12),方法如下:

1.prepareRefresh()  準備初始化

  方法內主要設置了容器的啓動時間和啓動標識,校驗屬性的合法性等。

2.obtainFreshBeanFactory()  獲取BeanFactory

  方法內主要對已有的Bean進行摧毀,關閉BeanFactory,並創建新的BeanFactory。然後解析配置文件,形成BeanDefinition對象,存儲起來。

3.prepareBeanFactory()  準備BeanFactory

  方法內都是Spring的特殊處理,主要對設置了BeanFactory的類加載器,註冊幾個Bean的後置處理器,忽略指定的Bean,註冊指定的Bean。

4.postProcesserBeanFactory()  Bean工廠的後置處理器

  這個方法是留給子類擴展的,子類可以通過添加一些特殊了BeanFactoryPostProcesser實現類,來完成一些其他操作。

5.invokeBeanFactoryPostProcesser()  執行Bean工廠後置處理器

  方法主要功能是調用BeanFactoryPostProcesser實現類的postProcessBeanFactory方法。

6.registerBeanPostProcessors()  註冊bean的後置處理器

  方法內主要是註冊BeanPostProcesser的實現類,

註冊順序:

①實現PriorityOrdered接口

②實現Ordered接口

③沒有實現任何優先接口

④實現MergedBeanDefinitionPostProcessor接口

  registerBeanPostProcessors方法所在的類有一個內部類BeanPostProcessorChecker,它裏面有兩個方法 PostProcesserBeforeInitialization (初始化之前執行)和PostProcesserAfterInitialization(初始化之後執行)。

注:AOP是在這裏被註冊的

7.initMessageSource()  初始化MessageSource  國際化處理

8.initApplicationEventMulticaster()  初始化事件派發器

9.onRefresh()  自定義刷新

  子類重寫這個方法,在容器刷新的時候可以自定義邏輯。

10.registerListeners()  註冊監聽器

11.finishBeanFactoryInitialization(beanFactory)  完成BeanFactory初始化

  程序執行到當前方法時已經執行了所有的BeanFactory後置處理器,並且加載了一些特殊的bean。這個方法主要會初始化剩下的沒有設置成懶加載模式的所有單例Bean。

12.finishRefresh() 完成刷新

  方法內初始化生命週期後置處理器,發佈容器刷新完成事件。

 

 

AOP創建過程


開啓AOP的兩種方式

1.註解 @EnableAspestJAutoProxy

前置通知(@Before):logStart:在目標方法div()運行之前運行
後置通知(@After):logEnd:在目標方法div()運行結束之後運行
返回通知(@AfterReturning):logReturn:在目標方法div()正常返回之後運行
異常通知(@AfterThrowing):logException:在目標方法div()出現異常之後運行

2.XML配置......

    <!-- 定義切面 -->
    <bean name="myAspectXML" class="com.zejian.spring.springAop.AspectJ.MyAspectXML" />
    <!-- 配置AOP 切面 -->
    <aop:config>
        <!-- 定義切點函數 -->
        <aop:pointcut id="pointcut" expression="execution(* com.zejian.spring.springAop.dao.ProductDao.add(..))" />

        <!-- 定義其他切點函數 -->
        <aop:pointcut id="delPointcut" expression="execution(* com.zejian.spring.springAop.dao.ProductDao.delete(..))" />

        <!-- 定義通知 order 定義優先級,值越小優先級越大-->
        <aop:aspect ref="myAspectXML" order="0">
            <!-- 定義通知   method 指定通知方法名,必須與MyAspectXML中的相同  pointcut 指定切點函數-->
            <aop:before method="before" pointcut-ref="pointcut" />

            <!-- 後置通知  returning="returnVal" 定義返回值 必須與類中聲明的名稱一樣-->
            <aop:after-returning method="afterReturn" pointcut-ref="pointcut"  returning="returnVal" />

            <!-- 環繞通知 -->
            <aop:around method="around" pointcut-ref="pointcut"  />

            <!--異常通知 throwing="throwable" 指定異常通知錯誤信息變量,必須與類中聲明的名稱一樣-->
            <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut" throwing="throwable"/>

            <!-- method : 通知的方法(最終通知)  pointcut-ref : 通知應用到的切點方法 -->
            <aop:after method="after" pointcut-ref="pointcut"/>
        </aop:aspect>
    </aop:config>

AOP創建過程

1.registerBeanPostProcessors() 註冊後置處理器;創建AnnotationAwareAspectJAutoProxyCreator

2.finishBeanFactoryInitialization() 初始化剩下的單實例bean
    2.1 創建業務邏輯和切面組件
    2.2 AnnotationAwaretJAutoProxyCreator攔截組件的創建過程
    2.3 組件創建完之後,判斷組件是否需要增強
          是:切面的通知方法,包裝成增強器(Advisor);給業務邏輯組件創建一個代理對象

3.執行目標方法:
   3.1 代理對象執行目標方法
   3.2 CglibAopProxy.intercept();
         3.2.1 得到目標方法的攔截器鏈(增強器包裝成攔截器MethodInterceptor)
         3.2.2 利用連接器的鏈式機制,依次進入每一個攔截器進行執行;
         3.2.3 效果:
                  正常執行:前置通知->目標方法->後置通知->返回通知
                  出現異常:前置通知->目標方法->後置通知->異常通知

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章