1.AOP相關術語介紹.avi(掌握)
目標對象target: 被代理增強的對象
連接點join point: 被攔截到的方法
切入點pointcut: 被攔截到的方法當中可以插入增強的方法
通知advice: 增強的代碼
切面aspect(關係): 通知和切點的結合,指定把什麼(增強)插入到哪裏(切點)去
織入weaving: 通知插入到切點的過程
代理 Proxy: 通知插入到切點通過代理完成的
引介 introduction:作用在類上,可以爲一個類增加屬性和方法
2.個人對於AOP的理解:
3.AOP在Spring中的實現原理:
1.我們首先從Spring 的 IOC 說起,Spring是一個管理 bean 的大工廠,只要放入到Spring管理的類,都可以從工廠BeanFactory(的子類
比如:ClassPathXmlApplicationContext)的getBean()方法獲得對象,創建過程是框架利用反射技術實現的,在創建過程中分了好多步驟:
Bean的生命週期:
1.instantiate bean對象實例化
2.populate properties 封裝屬性
3.如果Bean實現BeanNameAware執行setBeanName
4.如果Bean實現BeanFactoryAware或ApplicationContextAware設置工廠setBeanFactory或上下文對象setApplicationContext
5.如果存在類實現BeanPostProcessor(後處理Bean),執行postProcessBeforeInitialization
6.如果Bean實現InitializingBean執行afterPropertiesSet
7.調用自定義的init-method方法
8.如果存在類實現BeanPostProcessor(處理Bean),執行postProcessAfterInitialization
9.執行業務處理
10.如果Bean實現DisposableBean執行destroy
11.調用自定義的destroy-method
2.在上邊的bean聲明週期中的 第5步和第8步 有一個很重要的類:後處理bean: BeanPostProcessor 這個類中的方法
postProcessBeforeInitialization()在我們獲得到bean對象之前可以做攔截,它返回給我們什麼,我們就拿到了什麼,AOP也就是在這個
時候實現的;AOP最終的結果是要給我們的bean對象增強: 下面就來聊聊爲了實現AOP,我們都做了什麼:
1.我們要創建一個目標(target)類,裏邊有各種業務方法,然後將這個目標類註冊到Spring容器管理中;
2.我們創建一個通知類(xxxHelper 或者 xxxAdvice) ,裏邊是各種通知方法:
1. 前置通知Before 相當於BeforeAdvice
2. 後置通知AfterReturning 相當於AfterReturningAdvice
3. 環繞通知 Around 相當於MethodInterceptor
4. 拋出通知AfterThrowing 相當於ThrowAdvice
5. 引介通知DeclareParents 相當於IntroductionInterceptor
6. 最終通知After 不管是否異常,該通知都會執行
3.接下來我們要做的就是編寫一個切面:切面由 切點 和 通知組成
1.切點: 就是指定對那個方法,或者哪類方法增強,
2.通知: 就是指定如何對切點方法進行增強,
3.切面: 就是切點和通知的對應關係, 通過對切面的解析,我們就知道對哪個方法做什麼樣的增強;
4.這個時候在後處理bean 的postProcessBeforeInitialization()(或者 postProcessAfterInitialization())方法會首先攔截到
我們調用getBean()方法獲得的bean,然後拿着這個bean,利用動態代理技術,
1.給我們創建一個代理對象proxy,並返回;
2.在invoke方法中做方法增強:
1.根據切點攔截要增強的方法,
2.根據切面找到對應的增強,判斷是是何種增強,根據增強方式,做增強操作;這樣在我們用代理proxy調用核心業務
方法時,調用的是invoke方法中增強以後的方法;
4.代理工廠類做的事情:
當你給動態代理工廠一個需要被代理的對象 target 時,動態代理工廠用Proxy的API給你動態創建一個代理對象proxy,並且會同時給
這個代理對象綁定了一個invoke()方法(ps:這個invoke()方法是在一個 Invocation 類中定義的),這個invoke方法有何特
點呢? 1.因爲代理對象 proxy 是工廠給你的,這個invoke()方法也是工廠給你綁定的,所以,這個invoke()方法可以監聽到你在
什麼時候,調用了這個代理 proxy 的哪個方法 method(),所以一旦你調用代理的某個方法,馬上就會被invoke()方法監聽到,它可以馬上
獲得當前被調用的方法 method() 的對象 Method,以及調用方法的代理對象 proxy ,還有你調用方法時傳入的參數 Object[] params ;
當然,此時你也可以獲得被代理的對象 target(實際操作中是讓代理工廠實現了Invocation接口,那麼invoke()方法也在代理類中,所以在創
建代理類時通過構造傳參,將對象target傳過去),那麼此時此刻,你可以在invoke(),方法中直接 用你獲得的method對象,傳入被代理的對象
target 和 參數 params,這樣就完成了通過代理對象 proxy 調方法,實現了 目標對象 target 的相應方法被調用,但是,但是,如果你一旦
在invoke()方法中寫點兒其他東西,比如說:你在 Method 對象invoke之前或者之後 做了一些其他的操作,那麼這就意味着,此時此刻,你用
代理調用方法,不僅意味着目標對象target的相應方法被調用,而且同時執行了其他操作,這個就是動態代理實現了功能的增強;