文章大綱
一、AOP介紹
二、Spring的AOP實戰(zhàn)
三、AOP常用標簽
四、項目源碼及參考資料下載
五、參考文章

一、AOP介紹
1. 什么是AOP
在軟件業(yè),AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術。AOP是OOP的延續(xù),是軟件開發(fā)中的一個熱點,也是Spring框架中的一個重要內(nèi)容,是函數(shù)式編程的一種衍生范型。利用AOP可以對業(yè)務邏輯的各個部分進行隔離,從而使得業(yè)務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。
??簡單的說它就是把我們程序重復的代碼抽取出來,在需要執(zhí)行的時候,使用動態(tài)代理的技術,在不修改源碼的基礎上,對我們的已有方法進行增強。
2. AOP的作用及優(yōu)勢
??作用:在程序運行期間,不修改源碼對已有方法進行增強。
??優(yōu)勢:減少重復代碼 提高開發(fā)效率 維護方便
3. AOP的實現(xiàn)方式
??使用動態(tài)代理技術
二、Spring的AOP實戰(zhàn)
1. 相關術語介紹
(1)Joinpoint(連接點):所謂連接點是指那些被攔截到的點,spring中,這些點是指方法,因為spring只支持方法類型的連接點
(2)PointCut(切入點):所謂切入點是指我們要對哪些Joinpoint進行攔截的定義
(3)Advice(通知/增強):所謂通知是指攔截到Joinpoint之后所要做的事情就是通知,通知分為遷址通知、后置通知、異常通知、最終通知、環(huán)繞通知(切面要完成的功能)
??前置通知:在方法之前執(zhí)行
??后置通知:在方法之后執(zhí)行
??異常通知:方法出現(xiàn)異常
??最終通知:在后置之后執(zhí)行
??環(huán)繞通知:在方法之前和之后都執(zhí)行
(4)Aspect(切面):是切入點和通知(引介)的結(jié)合,把增強應用到具體方法上面,過程就叫切面。也就是把增強用到切入點的過程
2. 實現(xiàn)方式
(1)基于aspectJ的xml配置
(2)基于aspectJ的注解方式
3. 基于aspectJ的xml配置代碼實戰(zhàn)
創(chuàng)建測試類Book.java
package aop;
public class Book {
public void add() {
System.out.println("add.......");
}
}
創(chuàng)建增強、通知類MyBook.java
package aop;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyBook {
public void before1() {
System.out.println("前置增強...");
}
public void after1() {
System.out.println("后置增強...");
}
//環(huán)繞通知
public void around1(ProceedingJoinPoint proceedingJoinPoint) {
//方法之前
System.out.println("方法之前...");
//執(zhí)行被增強方法
try {
proceedingJoinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
//方法之后
System.out.println("方法之后...");
}
}
src下配置文件bean.xml
<?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.xsd"> <!-- bean definitions here -->
<!-- 配置兩個類的對象 -->
<bean id="book" class="aop.Book"></bean>
<bean id="myBook" class="aop.MyBook"></bean>
<!-- 配置aop操作 -->
<aop:config>
<!-- 配置切入點 expression就是寫表達式的,id就是切入點名字 -->
<aop:pointcut expression="execution(* aop.Book.*(..))" id="pointcut1"/>
<!-- 配置切面 把增強用到方法上面 ref是增強類的對象 -->
<aop:aspect ref="myBook">
<!-- 配置前置增強 method表示增強類里面使用哪個方法作為前置 pointcut-ref表示把增強方法配置到哪個切入點-->
<aop:before method="before1" pointcut-ref="pointcut1"/>
<!-- 配置后置增強 -->
<aop:after method="after1" pointcut-ref="pointcut1"/>
<!-- 配置環(huán)繞增強 -->
<aop:around method="around1" pointcut-ref="pointcut1"/>
</aop:aspect>
</aop:config>
</beans>
測試代碼如下
package aop;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAop {
@Test
public void testUser() {
//加載spring配置文件,根據(jù)內(nèi)容創(chuàng)建對象
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Book book = (Book) context.getBean("book");
book.add();
}
}
運行結(jié)果如下

4. 基于aspectJ的注解方式代碼實戰(zhàn)
創(chuàng)建測試類Book.java
??代碼與xml配置中一樣
創(chuàng)建增強、通知類MyBook.java
package aop2;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
//Spring就能發(fā)現(xiàn)用@Aspect注解的切面內(nèi)并把它應用到目標對象上。
@Aspect
public class MyBook {
//在方法上面使用注解完成增強配置
@Before(value="execution(* aop2.Book.*(..))")
public void before1() {
System.out.println("前置增強...");
}
@After(value="execution(* aop2.Book.*(..))")
public void after1() {
System.out.println("后置增強...");
}
@Around(value="execution(* aop2.Book.*(..))")
//環(huán)繞通知
public void around1(ProceedingJoinPoint proceedingJoinPoint) {
//方法之前
System.out.println("方法之前...");
//執(zhí)行被增強方法
try {
proceedingJoinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
//方法之后
System.out.println("方法之后...");
}
}
src下配置文件bean2.xml
<?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.xsd"> <!-- bean definitions here -->
<!-- 開啟aop操作 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- 創(chuàng)建對象 -->
<bean id="book" class="aop2.Book"></bean>
<bean id="myBook" class="aop2.MyBook"></bean>
</beans>
測試代碼如下
package aop2;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAop {
@Test
public void testUser() {
//加載spring配置文件,根據(jù)內(nèi)容創(chuàng)建對象
ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
Book book = (Book) context.getBean("book");
book.add();
}
}
運行結(jié)果如下

三、AOP常用標簽
(1)<aop:config>
??用于聲明開始aop的配置
(2)<aop:aspect>
??作用:用于配置切面。
??屬性:
??id:給切面提供一個唯一標識。
??ref:引用配置好的通知類bean的id。
(3)<aop:pointcut>
??作用:用于配置切入點表達式
??屬性:
??expression:用于定義切入點表達式。
??id:用于給切入點表達式提供一個唯一標識。
(4)<aop:before>
作用:用于配置前置通知
??屬性:
??method:指定通知中方法的名稱。
??pointct:定義切入點表達式
??pointcut-ref:指定切入點表達式的引用
(5)<aop:after-returning>
??作用:用于配置后置通知
??屬性:
??method:指定通知中方法的名稱。
??pointct:定義切入點表達式
??pointcut-ref:指定切入點表達式的引用
(6)<aop:after-throwing>
??作用:用于配置異常通知
??屬性:
??method:指定通知中方法的名稱。
??pointct:定義切入點表達式
??pointcut-ref:指定切入點表達式的引用
(7)<aop:after>
??作用:用于配置最終通知
??屬性:
??method:指定通知中方法的名稱。
??pointct:定義切入點表達式
??pointcut-ref:指定切入點表達式的引用
(8)<aop:around>
??作用:用于配置環(huán)繞通知
??屬性:
??method:指定通知中方法的名稱。
??pointct:定義切入點表達式
??pointcut-ref:指定切入點表達式的引用
四、項目源碼及參考資料下載
鏈接:https://pan.baidu.com/s/1mU6ktTrwggh9SVmsoucJRg
提取碼:jep8