AOP(Aspect Oriented Programming)是GoF四人組設計模式的一種擴展,設計模式所追求的是降低代碼之間的耦合度,增加程序的靈活性和可重用性,AOP實際上就是設計模式所追求的目標的一種實現。將通用的功能從不想通的類中分離,也就是多個類的共享行爲。AOP的核心思想類似動態代理模式,把共同的功能以額外功能的形式加入原始對象。面向對象的編程(OOP)方法是在面向過程的編程方法基礎上進行的改進,而面向方面編程(AOP)方法又是在面向對象編程(OOP)方法的基礎上進行改進而來的一種創新的軟件開發方法。AOP和OOP雖然在字面上十分相似,但是卻是面向不同領域的兩種設計思想。OOP(面向對象編程)針對問題領域中以及業務處理過程中存在的實體及其屬性和操作進行抽象和封裝,面向對象的核心概念是縱向結構的,其目的是獲得更加清晰高效的邏輯單元劃分;而AOP則是針對業務處理過程中的切面進行提取,例如,某一個操作在各個模塊中都有涉及,這個操作就可以看成“橫切”存在於系統當中。在許多情況下,這些操作都是與業務邏輯相關性不強或者不屬於邏輯操作的必須部分,而面向對象的方法很難對這種情況做出處理。AOP則將這些操作與業務邏輯分離,使程序員在編寫程序時可以專注於業務邏輯的處理,而利用AOP將貫穿於各個模塊間的橫切關注點自動耦合進來。AOP所面對的是處理過程中的某個步驟或階段,對不同的階段領域加以隔離,已獲得邏輯過程中各部分之間低耦合性的隔離效果,其與面向方面編程在目標上有着本質的差異。AOP的核心思想就是將應用程序中的業務邏輯處理部分同對其提供支持的通用服務,即所謂的“橫切關注點”進行分離,這些“橫切關注點”貫穿了程序中的多個縱向模塊的需求。
Spring提供了額外功能的4個接口
MethodBeforeAdvice
/** * 該額外功能在目標方法執行之前執行 */ public class BeforeAdviceDemo implements MethodBeforeAdvice { @Override /* * before:執行的外功能 @Method:當前增加了額外功能的目標方法 @Object[]:目標方法的參數 @Object:目標對象 */ public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("目標方法="+method.getName()); System.out.println("目標對象="+target.getClass()); System.out.println("-------執行的額外功能-------"); } }
AfterReturningAdvice【較少使用】
/**
* 額外功能在目標方法之後執行
*/
public class AfterAdviceDemo implements AfterReturningAdvice {
@Override
public void afterReturning(Object returnValue, Method method,
Object[] args, Object target) throws Throwable {
System.out.println("-----額外功能在目標方法執行之後-----");
}
}
MethodInterceptor
/**
* 額外功能在目標方法的前後執行
*
* @author Administrator
*
*/
public class RroundAdvice implements MethodInterceptor {
/*
* @MethodInvocation:代表目標對象 @return Object:目標方法值的返回值
*/
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("-----開啓事務------");
Object obj = null;
try {
obj = invocation.proceed();// 執行目標方法
} catch (Exception e) {
System.out.println("----事務回滾----");
return obj;
}
System.out.println("-----提交事務------");
return obj;
}
}
ThrowsAdvice
/**
* 額外功能在目標方法發生異常時執行
*
* @author Administrator
*
*/
public class ExceptionDemo implements ThrowsAdvice {
/*該方法從API中定義*/
public void afterThrowing(Method method, Object[] args, Object target,
Exception ex) {
System.out.println("-----發生了異常。。。-----");
}
}
在Spring AOP開發中,主要步驟
1.定義額外功能[根據功能選擇四個接口]
2.目標對象
3.切面【建議者】 NameMatchMethodPointcutAdvisor
4.配置Spring自動代理 BeanNameAutoProxyCreator
<beans xmlns="http://www.springframework.org/schema/beans"
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-3.0.xsd ">
<!-- 1.定義目標對象 -->
<bean id="userBiz" class="com.spring.biz.impl.UserBizImpl"></bean>
<bean id="orderBiz" class="com.spring.biz.impl.OrderBizImpl"></bean>
<!-- 2.定義額外功能 -->
<bean id="after" class="com.spring.advice.AfterAdviceDemo"></bean>
<bean id="before" class="com.spring.advice.BeforeAdviceDemo"></bean>
<bean id="round" class="com.spring.advice.RroundAdvice"></bean>
<bean id="excpe" class="com.spring.advice.ExceptionDemo"></bean>
<!-- 追加Spring建議者的配置,實現方法的過濾 -->
<bean id="methodPointCut"
class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<!-- 爲屬性注入,設定符合要求的方法和額外功能 -->
<property name="mappedNames"><!-- 指定方法的名稱那些方法需要額外功能,數組 -->
<list>
<value>log*</value><!-- 只對login方法追加額外功能,只關心方法名不關心目標對象 -->
<!-- 建議者中定義的方法名稱爲 切入點 -->
<value>sendCommit</value><!-- 追加sendCommit方法【切入點】 -->
</list>
</property>
<property name="advice" ref="round"><!-- 指定額外功能,對象 -->
</property>
</bean>
<!-- 3.創建Spring的動態代理對象:時一個複雜對象,通過id獲得的就是需要的代理類 -->
<bean id="userBizProxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 爲代理類定義目標對象和對應的額外功能 -->
<property name="target" ref="userBiz"><!--是ProxyFactoryBean的屬性,注入目標對象 -->
</property>
<property name="interceptorNames"><!--【數組】是ProxyFactoryBean的屬性,注入額外功能 -->
<list>
<!--<value>round</value> 直接定義額外功能的名稱 -->
<value>methodPointCut</value><!-- 如果有建議者,使用建議者名稱 -->
</list>
</property>
</bean>
<!-- 定義orderBiz的代理類 -->
<bean id="orderBizProxy"
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="orderBiz"></property>
<property name="interceptorNames">
<list>
<value>methodPointCut</value>
</list>
</property>
</bean>
</beans>
自動裝配
<bean id="autoProxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames"><!-- 注入原始對象 ,數組 -->
<list>
<!--<value>userBiz</value> 目標對象的id值 -->
<value>*Biz</value>
</list>
</property>
<property name="interceptorNames"><!-- 定義額外功能 -->
<list>
<value>methodPointCut</value>
</list>
</property>
</bean>