Spring之AOP詳解(非原創(chuàng))

文章大綱

一、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

五、參考文章

http://yun.itheima.com/course/215.html?1804lckj

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容