AOP是什麼?
Aspect Oriented Programming,即面向切面編程。
AOP把軟件系統分爲兩個部分:核心關注點和橫切關注點。
業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。
橫切關注點的一個特點是,他們經常發生在覈心關注點的多處,而各處基本相似,比如權限認證、日誌、事務。
AOP的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。
一些僞代碼
public class AccountServiceImpl implements IAccountService{ public void transfer(BigDecimal value){ try{ // 開啓事務 // 轉賬操作 // 提交事務 }catch(Exception e){ // 回滾事務 }finally{ // 關閉資源 } } }
其中轉賬操作就可以視爲核心關注點,事務相關的、關閉資源操作就可以視爲橫切關注點。
· AOP的目的
AOP能夠將那些與業務無關,卻爲業務模塊所共同調用的邏輯或責任(例如事務處理、日誌管理、權限控制等)封裝起來,
便於減少系統的重複代碼,降低模塊間的耦合度,並有利於未來的可拓展性和可維護性。
· AOP的實現
Spring的AOP使用了動態代理實現。
如果一個類實現了接口,那麼spring就使用JDK的動態代理完成AOP;
如果一個類沒有實現接口,那麼spring就使用cglib完成AOP。
· 一些概念
Aspect
切面。對橫切關注點的抽象。
做什麼增強?
日誌?事務?權限認證?what?
Pointcut
切入點。
在哪裏切入?
哪些類?哪些方法?where?
Adivice
增強,通知。
在什麼時候切入?
方法前?方法後?方法前後?when?
Weaving
織入。把切面加入到對象,並創建出代理對象的過程。
該過程由Spring來完成。
AOP的使用
· 切入點語法
AspectJ語言,由AOP聯盟制定規範。
語法 :execution(<修飾符>? <返回類型> <聲明類型>? <方法名>(<參數>) <異常>?)
如execution(* com.hanaii.pss.service.*Service.*(..))表示:
插入點爲com.hanaii.pss.service包下,以Service結尾的類的方法。
· 依賴的jar包
spring-aop-*.jar
com.springsource.org.aopalliance-*.jar
com.springsource.org.aspectj.weaver-*.jar
· 命名空間的配置
· xml配置
對下例配置文件進行解釋:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
">
<!-- 配置bean -->
<bean id="accountService" class="com.hanaii.aop.AccountServiceImpl"/>
<bean id="txManager" class="com.hanaii.aop.TransactionManager"/>
<!-- aop相關配置 -->
<aop:config>
<!-- what: 做什麼增強 -->
<aop:aspect ref="txManager" >
<!-- where: 在哪裏增強 -->
<aop:pointcut expression="execution(* com.hanaii.aop.*Service.*(..))" id="txPointcut"/>
<!-- when: 什麼時候增強 -->
<aop:before method="begin" pointcut-ref="txPointcut"/>
<aop:after-returning method="commit" pointcut-ref="txPointcut"/>
<aop:after-throwing method="rollback" pointcut-ref="txPointcut"/>
</aop:aspect>
</aop:config>
</beans>
<aop:config>
在該標籤中,進行aop相關的配置
<aop:aspect>
配置切面。
其ref屬性值爲增強類的bean id。
在該標籤中,對該增強類進行Pointcut和Advice的配置
<aop:pointcut>
配置切入點。
其expression屬性值爲切入點位置(AspectJ語言)。id屬性值爲該切入點的id。
Advice配置相關
增強的類型
配置相關部分標籤如上文配置文件。
其pointcut-ref屬性值爲切入點id。
· 增強類型之環繞增強 Around Advice
最強大的一種增強類型。
環繞增強可以在方法調用前後完成自定義的行爲。
環繞通知有兩個要求:
1、方法必須要返回一個Object(返回的結果)
2、方法的第一個參數必須是ProceedingJoinPoint(可以繼續向下傳遞的切入點)
ProceedingJoinPoint接口繼承於JoinPoint接口
其proceed方法的作用是讓目標方法執行。
JoinPoint
連接點
每個方法的前、後(兩者都有也行),或拋出異常是時都可以是連接點。
spring只支持方法連接點。其他如AspectJ還可以讓你在構造器或屬性注入時都行。
我們在想做增強的連接點,就是切入點(Ponitcut)。
Spring AOP那些學術概念—通知、增強處理連接點(JoinPoint)切面(Aspect)