Spring-AOP基礎

概念

1 AOP:面向切面(方面)編程。實現:擴展功能不修改源代碼

2 AOP 採取橫向抽取機制,取代了傳統縱向繼承體系重複性代碼

傳統縱向是指繼承、接口實現這兩種方式來實現代碼的拓展
橫向機制下面解釋

3 AOP底層 使用動態代理實現

(1)第一種情況,有接口情況,使用動態代理創建接口 實現 類代理對象

(2)第二種情況,沒有接口情況,使用動態代理創建類的子類 代理對象

原理

  • AOP:不修改代碼,但想要拓展原來的功能:
    在這裏插入圖片描述
  1. 最原始方法:修改代碼
  2. 傳統縱向機制:
    繼承父類
    缺點:父類名稱變化,子類的調用方法也要發生變化
  3. AOP動態代理實現:
    針對接口創建jdk代理,針對父類子類創建cglib動態代理
    在這裏插入圖片描述
    在這裏插入圖片描述
  • AOP方法:針對有接口的情況下

    • 創建一個與 實現接口類 平級的對象
    • 這個對象是代理對象 ,功能與 實現接口的類 相同
  • AOP:針對沒有接口的情況

    • 創建子類的代理對象
    • 調用父類的方法得到增強

AOP操作術語

Joinpoint(連接點): 類裏面可以被增強的方法,這些方法稱爲連接
Pointcut(切入點):所謂切入點是指我們要對哪些Joinpoint進行攔截的定義.
Advice(通知/增強):所謂通知是指攔截到Joinpoint之後所要做的事情就是通知.通知分爲前置通知,後置通知,異常通知,最終通知,環繞通知(切面要完成的功能)
Aspect(切面): 是切入點和通知(引介)的結合
Introduction(引介):引介是一種特殊的通知在不修改類代碼的前提下, Introduction可以在運行期爲類動態地添加一些方法或Field.
Target(目標對象):代理的目標對象(要增強的類)
Weaving(織入):是把增強應用到目標的過程.
把advice 應用到 target的過程
Proxy(代理):一個類被AOP織入增強後,就產生一個結果代理類

重點

  • 連接點:指的是可以被增強的方法
  • 切入點:在那些可以被增強的方法中,真正實際被增強了的方法
  • 通知/增強:讓add()增加一個日誌功能,這個日誌功能成爲增強
    //下面是具體實現
    1. 前置通知:在方法執行之前執行
    2. 後置通知:在方法執行之後執行
    3. 異常:方法出現異常
    4. 最終:在後置的後面執行
    5. 環繞:在方法執行之前和之後
  • 切面:把增強運用到具體的方法【即切入點】上的過程;

Spring的AOP操作

操作準備

  1. 除了導入基本的jar包之外,還需要導入aop相關的jar包

  2. 創建spring核心配置文件,導入aop的約束

<?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 -->

       
       </beans>

使用表達式配置切入點

切入點:實際增強的方法

常用的表達式
execution(<訪問修飾符>?<返回類型><方法名>(<參數>)<異常>)
(1)execution(* cn.itcast.aop.Book.add(…))
:只增強cn.itcast.aop.Book類裏面的add方法
(2)execution(* cn.itcast.aop.Book.*(…))
: cn.itcast.aop.Book.*所有方法
(3)execution(* .(…))
:所有類的所有方法
(4) execution(* save*(…)):匹配所有save開頭的方法

Aspectj的aop操作

目的:

  • 想要對Book類中的add方法進行加強
  • 創建myBook的before1方法,並且在add()方法執行之前,執行before方法(前置通知)

在目標方法執行之前執行

myBook的方法對Book的add方法進行前置增強

     <!-- 1 配置兩個對象 -->
        <bean id="book" class="cn.itclass.Aop.Book"></bean>
        <bean id="myBook" class="cn.itclass.Aop.MyBook"></bean>
        
        <!-- 2 配置AOP操作 -->
        <aop:config>
             <!-- 2.1 配置切入點 【被增強的方法】-->
             <aop:pointcut expression="execution(* cn.itclass.Aop.Book.add(..))" id="cutPoint1"/>
             
             <!-- 2.2 配置切面 : 把增強的方法(myBook)用到方法上
                                 ref:指的是增強的方法 (用myBook來增強Book,ref=myBook-->
             <aop:aspect ref="myBook">
                    <!-- 配置增強的類型
                          將增強和被增強的方法對應起來
                         method:使用增強類裏面具體哪個方法作爲前置(or後置等等)
                         pointcut-ref:指的是切入點
                     -->
                       <!-- 前置增強 -->
                     <aop:before method="before1" pointcut-ref="cutPoint1"/>
                     <!-- 環繞增強 -->
                     <aop:around method="around" pointcut-ref="cutPoint1"/>
                     <!-- 後置增強 -->
                     <aop:after-returning method="after1" pointcut-ref="cutPoint1"/>
             </aop:aspect>
        </aop:config>
</beans>



public class MyBook {
	//前置增強
	public void before1() {
		System.out.println("before.......");
	}
	//環繞增強
	
	public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		/*
		 * 1.先執行第一個
		 * 2. 執行原來的功能
		 * 3.執行添加的第二個功能
		 */
		//功能之前:
		System.out.println("我在環繞之前執行");
		//執行原有功能
		proceedingJoinPoint.proceed();
		//執行之後的功能
		System.out.println("我是之後的功能");
	}
	//後置增強
	public void after1() {
		System.out.println("after........");
	}
}
發佈了16 篇原創文章 · 獲贊 7 · 訪問量 4180
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章