SpringAOE的程式碼實現(未完工)

cuixiaoming1994發表於2018-03-25

AOE簡介

1、aop的概述
aop:面向切面程式設計

程式導向語言:C等
面嚮物件語言OOP:java等
面向切面程式設計AOP:在不修改原始碼的情況下 對目標方法進行增強 (方法解耦和)
面向服務架構SOA:圍繞是系統的開發進行專案拆分

AOP優點:程式碼重用性提高 降低程式碼的耦合性 在不修改原始碼的情況下 對目標方法進行增強

2、aop的底層實現–動態代理
JDK的基於介面的動態代理
CGlib基於父類的動態代理
相關實現程式碼見上一篇文章:動態代理

3、aop相關的術語
目標物件:target
代理物件:proxy
連線點:joinPoint 可能被增強的方法
切(入)點:pointCut 真正被增強的方法(配置切點表示式:告知spring哪些方法被增強)
通知:Advice 增強方法
切面:Aspect =切點+通知
織入:Weaving 是個動詞,代表是切點與通知的結合過程叫做織入(織入的配置是AOE的重點)
引介:動態在代理物件中 生成新的欄位 方法 ….

xml配置方式

1、除了核心包外還需要匯入aop相關的jar包
spring-aop-4.2.4.RELEASE.jar包
spring-aspects-4.2.4.RELEASE.jar包
com.springsource.org.aopalliance-1.0.0.jar包 —aop聯盟
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar包
aspectj的織入的包

2.建立介面和目標類
介面

package com.cuixiaoming.aop.xml;

public interface TargetInterface {

    void targetMethod();
}

目標類

package com.cuixiaoming.aop.xml;

public class Target implements  TargetInterface {

    @Override
    public void targetMethod() {
        System.out.println("目標方法開始執行");


        //int a= 1/0;//用於測試異常丟擲
        System.out.println("目標方法執行完畢");
    }
}

3、建立切面類(包含通知)
PS:切面=切點+通知 建立切面是不完整 缺少切點 通過織入將切點與增強在切面內部結合
建立MyAspect
通知的分類見下面xml配置
這裡的方法名可以隨意配置

package com.cuixiaoming.aop.xml;

import org.aspectj.lang.ProceedingJoinPoint;

//切面物件
public class MyAspect {

    public void before(){
        System.out.println("before:前置增強");
    }

    public void afterReturning(){
        System.out.println("afterReturning:後置增強");
    }

    //使用環繞的時候需要執行切入點方法
    public void around(ProceedingJoinPoint pjp) throws Throwable{
        System.out.println("around:前置增強");
        pjp.proceed();//執行切點方法
        System.out.println("around:後置增強");
    }

    //目標方法出現異常,報錯之前執行該方法
    public void afterThrowing(){
        System.out.println("afterThrowing:丟擲異常增強");
    }


    //最終的意思是,就算報錯也會執行,但是並不一定最終執行
    public void after(){
        System.out.println("after:最終增強");
    }

}

我們在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:context="http://www.springframework.org/schema/context"
       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
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

</beans>

將目標物件和切面物件進行配置

   <!--目標物件-->
    <bean id="target" class="com.cuixiaoming.aop.xml.Target"></bean>

    <!--通知類-->
    <bean id="myAspect" class="com.cuixiaoming.aop.xml.MyAspect"></bean>

下面對織入過程進行配置

<aop:config>

    <!--在哪一個類裡面裝了通知方法-->
    <aop:aspect ref="myAspect">

    <!-- 在這裡配置通知方法 -->


</aop:config>
  • 通知的分類 (以在xml中標籤的名字區分,在建立通知方法的時候,可以隨意起名字,在xml中進行配置就可以了)
    • aop:before:前置增強
    • aop:after-returning:後置增強
    • aop:around:環繞增強 (前置+後置)
      • 這個需要注意一下,需要在前後置程式碼之間執行目標方法—>pjp.proceed();
    • aop:after-throwing:異常丟擲增強
      • 在目標方法報錯的時候,在錯誤資訊之前執行
    • aop:after:最終增強
      • 最終增強的意思不是最後執行,而是總會執行,就算報錯也會執行的增強,他的執行順序不確定

下面以before為例子

<aop:before method="before" pointcut="execution(public void com.cuixiaoming.aop.xml.Target.targetMethod())"></aop:before>

這是一種基本的寫法.pointcut裡面裝的是切點表示式

切點表示式

pointcut="execution(public void com.itheima.aop.xml.Target.targetMethod())"
語法:
pointcut="execution([訪問修飾符] 返回值 包.類.方法(引數列表))"
切點表示式用來定義哪些連線點是切點
注意:
1. 訪問修飾符可以省略
2. 返回值、包、類、方法 可以使用 * 代表任意
3. 引數列表可以使用 .. 代表任意

 常用的配置:
        void com.itheima.aop.xml.Target.targetMethod()
        * com.itheima.aop.xml.Target.*()    //指定類中任意無參方法
        * com.itheima.aop.xml.Target.*(..)    //指定類中任意方法
        * com.itheima.aop.xml.*.*(..)    //指定包中任意類中任意方法(常用)
        * com.itheima.aop.xml..*.*(..)    //指定包中

相關文章