AOP一般被稱爲實現橫切關注點的工具.java
橫切關注點:通常是不能從應用程序中分離出來,但同時又致使代碼重複,緊密耦合的業務邏輯.spring
最多見的橫切關注點:dao層的數據庫操做.操做數據時(增長,更新,刪除)就必須進行事務管理,若是沒有AOP,那麼事務管理的代碼會大量重複並且與應用緊密耦合.數據庫
AOP的分類:
靜態AOP(AspectJ):
在編譯時就將橫切邏輯織入了字節碼文件,程序運行時不需再進行判斷;
要改變橫切邏輯,就必須修改源碼再從新編譯;
動態AOP(Spring):
在運行時根據配置判斷符合規則的鏈接點,再動態生成相應的代理類來添加橫切邏輯;
要改變橫切邏輯,只須要修改AOP配置便可;ide
AOP的一些概念和術語工具
Joinpoints(鏈接點) | 鏈接點是應用程序執行過程當中定義明確的點.鏈接點的典型例子有:調用一個方法,class初始化,對象初始化.鏈接點是AOP的一個核心概念,它決定了在你的應該中的哪些點可使用AOP來插入一些額外的業務. |
Advice(通知) | 類中定義的在一個特定鏈接點執行的方法就是advice.advice有多類如:before,after,around;即在鏈接點前執行的advice,鏈接點後執行的advice,在鏈接點先後都執行 |
Pointcuts(切入點) | 切入點是一組鏈接點的集合,用來定義何時advice應該執行.經過建立切入點,你能夠更細粒度的控制在應用程序中如何使用advice. |
Aspects(切面) | 封裝在一個類中的pointcuts與advice組合起來就是一個切面.這就決定了應用程序中的一些業務應該在何時什麼地方執行 |
Weaving(織入) | 這是將切面在合適的點插入應用程序編碼的過程.對於編譯時AOP的解決方案,織入一般是在構建時完成.一樣的,對於運行時AOP的解決方案,織入是在運行時動態執行.AspectJ支持另一種叫load-time weaving (LTW)的織入機制,當它被字節碼裝載器裝載後它會攔截底層JVM的字節碼裝載器,並向字節碼中進行織入. |
Target(目標) | 被AOP改變了執行流程的對象被稱爲目標對象.一般被稱爲advised object |
Introduction(引入) | 修改一個類的結構爲其引入額外的方法或字段的過程就是引入.你可使用引入AOP讓一個對象實現一個特定的接口,而不須要對象的Class來明確實現該接口. |
Spring中的Joinpoints:只支持方法調用編碼
Spring中的Aspects:
每一個Aspect都必須實現Advisor接口;Spring默認提供了2個便捷的實現類:PointcutAdvisor和IntroductionAdvisor;
PointcustAdvisor:是經過pointcut來控制將advice添加到joinpoints;
IntroductionAdvisor:是比較特殊的一類advice.spa
Spring中的Advice類型:
.net
Before | org.springframework.aop.MethodBeforeAdvice |
After-returning | org.springframework.aop.AfterReturningAdvice |
After (finally) | org.springframework.aop.AfterAdvice |
Around | org.aopalliance.intercept.MethodInterceptor |
Throws | org.springframework.aop.ThrowsAdvice |
Introduction | org.springframework.aop.IntroductionInterceptor |
AOP示例代理
package aop; // AOP中的Target public class MessageWriter { public void writeMessage() { System.out.print("World"); } }
經過AOP實現輸出:Hello World!code
package aop; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; // AOP中的Advice,類型爲around public class MessageDecorator implements MethodInterceptor { @Override public Object invoke(MethodInvocation invocation) throws Throwable { System.out.print("Hello "); Object retVal = invocation.proceed(); System.out.println("!"); return retVal; } }
package aop; import org.springframework.aop.framework.ProxyFactory; public class HelloWorldAOPExample { public static void main(String[] args) { MessageWriter target = new MessageWriter(); ProxyFactory pf = new ProxyFactory(); // 底層委託給 addAdvisor()方法,將其包裝爲 DefaultIntroductionAdvisor 或 DefaultPointcutAdvisor pf.addAdvice(new MessageDecorator()); pf.setTarget(target); MessageWriter proxy = (MessageWriter) pf.getProxy(); target.writeMessage(); System.out.println(""); proxy.writeMessage(); } }
由此能夠看出Spring中的AOP本質上是經過動態代理實現的(詳細見AOP(二))
示例中AOP把被代理對象的全部方法都進行了代理,實際應用中可能只須要代理部分方法.固然Spring對這種也提供了支持:Pointcuts,Advisor(詳細見AOP(三))