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 事務
學習是永無止境的。