天天看點

Spring5入門到實戰------10、操作術語解釋--Aspectj注解開發執行個體。AOP切面程式設計的實際應用

1、操作術語

1.1、連接配接點

類裡面哪些方法可以被增強、這些方法被稱為連接配接點。比如:使用者控制層有登入、注冊、修改密碼、修改資訊等方法。假如隻有登入類和注冊類可以被增強,登入和注冊方法就稱為連接配接點

1.2、切入點

實際被真正增強的方法,稱為切入點。假如登入方法被正真增強(登陸前做些權限驗證之類的、假設原始方法隻是查詢資料庫、無權限認證過程)、登入方法又稱為切入點。

1.3、通知(增強)

實際增強的邏輯部分稱為通知(增強)。你編寫的新的業務邏輯、比如在登入前進行的權限認證操作。

通知有多種類型

  • 前置通知
  • 後置通知
  • 環繞通知
  • 異常通知
  • 最終通知

1.4、切面

把通知應用到切入點過程。你編寫的業務邏輯(通知)如何加入到之前的方法(切入點)

2、準備工作和如何使用

友情提示:如果直接建立spring項目、則不需要進行這一步

2.1

2.1 jar包引入

1、Spring 架構一般都是基于 AspectJ 實作 AOP 操作

  • AspectJ 不是 Spring 組成部分,獨立 AOP 架構,一般把 AspectJ 和 Spirng 架構一起使用,進行 AOP 操作

2、基于 AspectJ 實作 AOP 操作

  • 基于 xml 配置檔案實作
  • 基于注解方式實作(使用)

3、在項目工程裡面引入 AOP 相關依賴

Spring5入門到實戰------10、操作術語解釋--Aspectj注解開發執行個體。AOP切面程式設計的實際應用

2.2、切入點表達式(具體使用)

(1)切入點表達式作用:知道對哪個類裡面的哪個方法進行增強
(2)文法結構: execution([權限修飾符] [傳回類型] [類全路徑] [方法名稱]([參數清單]) )      

例子

舉例 1:對 com.zyz.dao.BookDao 類裡面的 add 進行增強
execution(* com.zyz.dao.BookDao.add(..))

舉例 2:對 com.zyz.dao.BookDao 類裡面的所有的方法進行增強
execution(* com.zyz.dao.BookDao.* (..))

舉例 3:對 com.zyz.dao 包裡面所有類,類裡面所有方法進行增強
execution(* com.zyz.dao.*.* (..))      

3、代碼實戰

3.1 User .java

一個類裡邊的基本方法。 使用注解​

​@Component​

​建立 User 對象。
/**
 * @author Lenovo
 * @version 1.0
 * @data 2022/10/20 22:16
 */
@Component
public class User {
    public void add(){
//        int a = 1/0;
        System.out.println("add......");
    }

}      

3.2 UserProxy .java

1、代理類中進行方法的增強。

2、使用注解​​

​@Component​

​​建立 UserProxy 對象。

3、在增強類上面添加注解 @Aspec。

4、增強類的裡面,在作為通知方法上面添加通知類型注解,使用切入點表達式配置

/**
 * 增強的類
 * @author Lenovo
 * @version 1.0
 * @data 2022/10/20 22:19
 */
@Component
@Aspect//生成代理對象
public class UserProxy {

    /**
     * 1、前置通知
     */
    @Before(value = "execution(* com.zyz.spring5.aop.User.add(..))")
    public void before(){
        System.out.println("before。。。。。。");
    }

    /**
     * 2、後置通知
     */
    @AfterReturning(value = "execution(* com.zyz.spring5.aop.User.add(..))")
    public void afterReturnning(){
        System.out.println("afterReturnning。。。。。。");
    }


    /**
     * 3、最終通知
     */
    @After(value = "execution(* com.zyz.spring5.aop.User.add(..))")
    public void after(){
        System.out.println("after。。。。。。");
    }

    /**
     * 4、異常通知
     */
    @AfterThrowing(value = "execution(* com.zyz.spring5.aop.User.add(..))")
    public void afterThrowing(){
        System.out.println("afterThrowing。。。。。。");
    }

    /**
     * 5、環繞通知
     * @param proceedingJoinPoint
     * @throws Throwable
     */
    @Around(value = "execution(* com.zyz.spring5.aop.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("環繞之前。。。。。。。");
        //被增強的方法執行
        proceedingJoinPoint.proceed();
        System.out.println("環繞之後。。。。。。。");
    }


}      

3.3 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: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/context http://www.springframework.org/schema/context/spring-context.xsd
                            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

    <!-- 開啟注解掃描 -->
    <context:component-scan base-package="com.zyz.spring5.aop"></context:component-scan>

    <!-- 開啟 Aspect 生成代理對象-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>


</beans>      

3.4 測試類

/**
 * @author Lenovo
 * @version 1.0
 * @data 2022/10/20 22:38
 */
public class Test {

    @org.junit.Test
    public void testDemo(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        User user = context.getBean("user", User.class);
        user.add();

    }
}      

3.5 測試結果

Spring5入門到實戰------10、操作術語解釋--Aspectj注解開發執行個體。AOP切面程式設計的實際應用
Spring5入門到實戰------10、操作術語解釋--Aspectj注解開發執行個體。AOP切面程式設計的實際應用

4、優化代碼

4.1 相同的切入點抽取

仔細看代碼不難發現、耦合性很高。比如增強的方法類的位置移動。那麼所有增強的表達式中的路徑也要一個一個改動(3.2 UserProxy.java)

相同的切入點抽取、達到複用的效果。可以隻需要改動少量的代碼、完成相同的事情。便于後期的維護

/**
 * 增強的類
 * @author Lenovo
 * @version 1.0
 * @data 2022/10/20 22:19
 */
@Component
@Aspect//生成代理對象
public class UserProxy {
    /**
     * 相同切入點抽取
     */
    @Pointcut(value = "execution(* com.zyz.spring5.aop.User.add(..))")
    public void pointDemo(){}


    /**
     * 1、前置通知
     */
    @Before(value = "pointDemo()")
    public void before(){
        System.out.println("before。。。。。。");
    }

    /**
     * 2、後置通知
     */
    @AfterReturning(value = "pointDemo()")
    public void afterReturnning(){
        System.out.println("afterReturnning。。。。。。");
    }


    /**
     * 3、最終通知
     */
    @After(value = "pointDemo()")
    public void after(){
        System.out.println("after。。。。。。");
    }

    /**
     * 4、異常通知
     */
    @AfterThrowing(value = "pointDemo()")
    public void afterThrowing(){
        System.out.println("afterThrowing。。。。。。");
    }

    /**
     * 5、環繞通知
     * @param proceedingJoinPoint
     * @throws Throwable
     */
    @Around(value = "pointDemo()")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("環繞之前。。。。。。。");
        //被增強的方法執行
        proceedingJoinPoint.proceed();
        System.out.println("環繞之後。。。。。。。");
    }


}      

4.2 有多個增強類多同一個方法進行增強,設定增強類優先級

​@Order(1)​

​數字越小優先級越高
@Component
@Aspect
@Order(1)
public class UserProxy1      
Spring5入門到實戰------10、操作術語解釋--Aspectj注解開發執行個體。AOP切面程式設計的實際應用

建立一個增強類1

/**
 * @author Lenovo
 * @version 1.0
 * @data 2022/10/22 18:50
 */
@Component
@Aspect
@Order(1)
public class UserProxy1 {

    /**
     * 1、前置通知
     */
    @Before(value = "execution(* com.zyz.spring5.aop.User.add(..))")
    public void before(){
        System.out.println("我的優先級高哦、我先執行。before。。。。。。");
    }
}      

之前的增強類也添加一個優先級

@Component
@Aspect//生成代理對象
@Order(3)
public class UserProxy {      

測試結果

Spring5入門到實戰------10、操作術語解釋--Aspectj注解開發執行個體。AOP切面程式設計的實際應用

5、完全注解開發

5.1 新增一個配置類

ConfigAop.java

/**
 * @author Lenovo
 * @version 1.0
 * @data 2022/10/22 18:58
 */
@Configuration
@ComponentScan(basePackages = {"com.zyz"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class ConfigAop {
}      

5.2 測試方式改動

之前讀取的是配置檔案。現在要讀取配置類
@org.junit.Test
    public void testDemo1(){
        //加載配置類
        ApplicationContext context = new AnnotationConfigApplicationContext(ConfigAop.class);
        User user = context.getBean("user", User.class);
        user.add();

    }      

測試結果不變

Spring5入門到實戰------10、操作術語解釋--Aspectj注解開發執行個體。AOP切面程式設計的實際應用

目錄結構

6、後語