Spring AOP詳解
一.前言
在以前的項目中,很少去關注spring aop的具體實現與理論,只是簡單瞭解了一下什麼是aop具體怎麼用,看到了一篇博文寫得還不錯,就轉載來學習一下,博文地址:http://www.cnblogs.com/xrq730/p/4919025.html
AOP
AOP(Aspect Oriented Programming),即面向切面編程,可以說是OOP(Object Oriented Programming,面向對象編程)的補充和完善。OOP引入封裝、繼承、多態等概念來建立一種對象層次結構,用於模擬公共行爲的一個集合。不過OOP允許開發者定義縱向的關係,但並不適合定義橫向的關係,例如日誌功能。日誌代碼往往橫向地散佈在所有對象層次中,而與它對應的對象的核心功能毫無關係對於其他類型的代碼,如安全性、異常處理和透明的持續性也都是如此,這種散佈在各處的無關的代碼被稱爲橫切(cross cutting),在OOP設計中,它導致了大量代碼的重複,而不利於各個模塊的重用。
AOP技術恰恰相反,它利用一種稱爲"橫切"的技術,剖解開封裝的對象內部,並將那些影響了多個類的公共行爲封裝到一個可重用模塊,並將其命名爲"Aspect",即切面。所謂"切面",簡單說就是那些與業務無關,卻爲業務模塊所共同調用的邏輯或責任封裝起來,便於減少系統的重複代碼,降低模塊之間的耦合度,並有利於未來的可操作性和可維護性。
使用"橫切"技術,AOP把軟件系統分爲兩個部分:核心關注點和橫切關注點。業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在覈心關注點的多處,而各處基本相似,比如權限認證、日誌、事物。AOP的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。
AOP核心概念
1、橫切關注點
對哪些方法進行攔截,攔截後怎麼處理,這些關注點稱之爲橫切關注點
2、切面(aspect)
類是對物體特徵的抽象,切面就是對橫切關注點的抽象
3、連接點(joinpoint)
被攔截到的點,因爲Spring只支持方法類型的連接點,所以在Spring中連接點指的就是被攔截到的方法,實際上連接點還可以是字段或者構造器
4、切入點(pointcut)
對連接點進行攔截的定義
5、通知(advice)
所謂通知指的就是指攔截到連接點之後要執行的代碼,通知分爲前置、後置、異常、最終、環繞通知五類
6、目標對象
代理的目標對象
7、織入(weave)
將切面應用到目標對象並導致代理對象創建的過程
8、引入(introduction)
在不修改代碼的前提下,引入可以在運行期爲類動態地添加一些方法或字段
Spring對AOP的支持
Spring中AOP代理由Spring的IOC容器負責生成、管理,其依賴關係也由IOC容器負責管理。因此,AOP代理可以直接使用容器中的其它bean實例作爲目標,這種關係可由IOC容器的依賴注入提供。Spring創建代理的規則爲:
1、默認使用Java動態代理來創建AOP代理,這樣就可以爲任何接口實例創建代理了
2、當需要代理的類不是代理接口的時候,Spring會切換爲使用CGLIB代理,也可強制使用CGLIB
AOP編程其實是很簡單的事情,縱觀AOP編程,程序員只需要參與三個部分:
1、定義普通業務組件
2、定義切入點,一個切入點可能橫切多個業務組件
3、定義增強處理,增強處理就是在AOP框架爲普通業務組件織入的處理動作
所以進行AOP編程的關鍵就是定義切入點和定義增強處理,一旦定義了合適的切入點和增強處理,AOP框架將自動生成AOP代理,即:代理對象的方法=增強處理+被代理對象的方法。
下面是代碼示例:
package AopTest;
public class Student {
public String print(String msg) {
System.out.println(msg);
return "HelloWorld";
}
}
package AopTest;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import java.lang.Throwable;
@Aspect
public class StuInterceptor {
/*
* 打印方法
* "*"表示返回值爲任意類型,printMsg爲執行的方法,".."表示參數爲任意類型
*/
@Pointcut("execution(* AopTest.Student.print(..))")
public void printMethod() {
}
/*
* 前置通知
*/
@Before("printMethod()")
public void printBeforeAdvice() {
System.out.println("printBeforeAdvice()!");
}
/*
* 後置通知
*/
@AfterReturning(pointcut = "printMethod()",returning = "flag")
public void printAfterAdvice(String flag) {
System.out.println("printAfterAdvice()!" + flag);
}
@After("printMethod()")
public void finallyAdvice() {
System.out.println("fianllyAdvice()!");
}
/*
* args(name) 表示可以傳遞參數
*/
@Around("printMethod() && args(name)")
public Object printAroundAdvice(ProceedingJoinPoint pjp,String name) throws Throwable {
Object result = null;
if (name.equals("whc")) {
pjp.proceed();
}else {
System.out.println("printMsg 方法以及被攔截。。。");
}
return result;
}
}
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:annotation-config />
<context:component-scan base-package="AopTest"/>
<aop:aspectj-autoproxy />
<bean id="stu" class="AopTest.Student"></bean>
<bean id="stuInterceptor" class="AopTest.StuInterceptor"></bean>
</beans>
package AopTest; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { @SuppressWarnings("resource") ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/conf.xml"); Student stu = (Student)ctx.getBean("stu"); stu.print("whc"); } }
注意需要使用AspectJ需要引入一些jar包:
aopalliance.jar
aspectjrt.jar
aspectjtools.jar
aspectjweaver.jar
org.aspectj.matcher.jar
可以根據需要引入上面的部分包,不一定全部需要引入,然後就可以編譯通過了,
如果還缺其他的包,可以百度查,然後下載下來就可以了。
資源下載地址:http://download.csdn.net/download/a1317338022/10130277