Spring中三大核心思想之一AOP(面向切麵編程): 在軟體業,AOP為Aspect Oriented Programming的縮寫,意為:面向切麵編程,通過預編譯方式和運行期動態代理實現程式功能的統一維護的一種技術。AOP是OOP的延續,是軟體開發中的一個熱點,也是Spring框架中的一個重要內 ...
Spring中三大核心思想之一AOP(面向切麵編程):
在軟體業,AOP為Aspect Oriented Programming的縮寫,意為:面向切麵編程,通過預編譯方式和運行期動態代理實現程式功能的統一維護的一種技術。AOP是OOP的延續,是軟體開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生範型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程式的可重用性,同時提高了開發的效率。通過預編譯方式和運行期動態代理實現程式功能的統一維護的一種技術。 (更深入請百度) Spring 2.0在AOP上有很大的改進。首先,AOP XML的配置更加簡單了,Spring2.0引入了新的模式,支持定義從常規Java對象中發展來的切麵,充分利用了AspectJ切入點語言,提供了完整類型的Advice(也就是沒有多餘轉換和Object[] 參數操作)。另外,得意於Annotation的發展,Spring2.0提供了對@AspectJ切麵的支持,這些切麵可以在AspectJ與Spring AOP中共用,需要的僅僅是簡單的配置。 AOP機制? 使用AOP仍然需要修改所有的方法,但是修改這個方法的過程由Spring來幫我們完成 AOP通知類型: 前置通知,關鍵詞before。指的是在一個方法執行前通知。 後置通知,關鍵詞after。指的是在一個方法執行後進行通知。 環繞通知,關鍵詞around。值的是在一個方法之前與之後執行進行通知。 異常拋出後通知,throw。在一個方法執行過程中之後並且拋出異常進行通知。 操作代碼記錄:<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd"> <!-- 定義bean --> <bean id="stuService" class="com.lxit.aop.service.StudentService" /> <!-- AOP配置 --> <!-- 添加Aspect的bean --> <bean id="logAspect" class="com.lxit.aop.aspect.LogAspect" /> <aop:config> <!-- 定義一個pointcut --> <aop:pointcut id="servicepointcut" expression="execution(* com.lxit.aop.service.*.*(..))" /> <!-- 定義aspect,引用生成的aspectBean 並指定pointcut 和 method--> <aop:aspect id="aspect1" ref="logAspect"> <aop:after pointcut-ref="servicepointcut" method="logAdd" /> </aop:aspect> </aop:config> </beans>
public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml"); StudentService service = (StudentService) ac.getBean("stuService"); service.add(); service.getStudent(); }
異常拋出增強:
異常拋出增強的特點是在目標方法拋出異常時織入增強處理,
但是異常處理一般會需要獲取異常參數。
在配置文件中添加異常處理的aspect。
使用<aop:after-throwing來進行異常織入。
public class ExceptionAspect { public void exceptionLog(Exception e){ System.out.println("發生異常,寫入日誌。" + e.getMessage()); } }
<bean id="exceptionAspect" class="com.lxit.aop.aspect.ExceptionAspect" /> <aop:config> <!-- 定義一個pointcut --> <aop:pointcut id="servicepointcut" expression="execution(* com.lxit.aop.service.*.*(..))" /> <!-- 定義aspect,引用生成的aspectBean 並指定pointcut 和 method--> <aop:aspect id="aspect2" ref="exceptionAspect"> <!-- 表示當程式發生異常後才織入 --> <aop:after-throwing method="exceptionLog" pointcut-ref="servicepointcut" throwing="e"/> </aop:aspect> </aop:config>
環繞增強:
環繞增強在目標方法的前後都可以織入增強處理
環繞增強是功能最強大的增強處理,Spring把目標方法的控制權全部交給了它
在環繞增強處理中,可以獲取或修改目標方法的參數、返回值,可以對它進行異常處理,甚至可以決定目標方法是否執行
public class AroundLogger { public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable { … } }
<bean id="theLogger" class="aop. AroundLogger"></bean>
<aop:config>
<aop:pointcut id="pointcut" expression="execution(* biz.IUserBiz.*(..))" />
<aop:aspect ref="theLogger">
<aop:around method="aroundLogger" pointcut-ref="pointcut" />
</aop:aspect>
</aop:config>
五中織入方式的區別:
<aop:before …>:在目標方法調用之前織入。
只要before方法執行完成,目標方法總會被調用,但before可以通過拋出異常來阻止目標方法執行,before不能訪問目標方法的返回值。
<aop:after…>:在目標方法調用之後織入。
after不能組織目標方法的執行,after不能訪問目標方法的返回值。
<aop:after-throwing..>:拋出異常時織入。如果指定throwing必須指定一個異常參數,增強方法中必須和此參數同名,類型必須大於該異常類型。
<aop:after-returning…>:在目標方法成功執行之後織入。
after-returning:不能阻止目標方法的執行,可以訪問目標方法的返回值,但不能修改。
<aop:around…>:在目標方法調用之前和調用之後織入。它的處理方法必須包含一個ProceedingJoinPoint形參。
aop:around:可以組織目標方法的執行,可以訪問目標方法的返回值,可以修改返回值。
以上增強器都可以指定args來指定參數
在Struts2,hibernate,Spring整合中就可以看到一種很好的效果。
在serivce層定義成一個切點在執行操作前可以開啟一系列操作,比如寫入日誌,事務等操作是一種典型的案例。
AOP使用場景
AOP用來封裝橫切關註點,具體可以在下麵的場景中使用:
Authentication 許可權 Caching 緩存 Context passing 內容傳遞 Error handling 錯誤處理 Lazy loading 懶載入
Debugging 調試 logging, tracing, profiling and monitoring 記錄跟蹤 優化 校準 Performance optimization 性能優化
Persistence 持久化 Resource pooling 資源池 Synchronization 同步 Transactions 事務