javascript
Spring基于AspectJ实现AOP操作
基于AspectJ實現AOP操作
- 準備工作
- 在項目工程里面引入 AOP 相關依賴。
- 如果是maven項目,使用pom.xml代替引入jar包的過程(注意)
- 學會使用切入點表達式
- AOP 操作(AspectJ 注解)
- 1、創建類,在類里面定義方法
- 2、創建增強類(編寫增強邏輯),在增強類里面,創建方法,讓不同方法代表不同通知類型
- 3、進行通知的配置
- 4、配置不同類型的通知
- 相同的切入點抽取
- 有多個增強類多同一個方法進行增強,設置增強類優先級
- 完全使用注解開發
- 代碼結構
- 測試代碼
Spring 框架一般都是基于 AspectJ 實現 AOP 操作。
需要注意的是:AspectJ 不是 Spring 組成部分,獨立 AOP 框架,一般把 AspectJ 和 Spirng 框架一起使用,進行 AOP 操作。
基于 AspectJ 實現 AOP 操作有兩種方式:
(1)基于 xml 配置文件實現
(2)基于注解方式實現(普遍使用)
準備工作
在項目工程里面引入 AOP 相關依賴。
需要以下這些依賴:
如果是maven項目,使用pom.xml代替引入jar包的過程(注意)
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.Keafmd</groupId><artifactId>day04_eesy_01jdbctemplate</artifactId><version>1.0-SNAPSHOT</version><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>7</source><target>7</target></configuration></plugin></plugins></build><packaging>jar</packaging><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.2.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.7.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.2.7.RELEASE</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.46</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.10</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.9</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>compile</scope></dependency></dependencies></project>學會使用切入點表達式
切入點表達式作用(通俗的講):知道對哪個類里面的哪個方法進行增強。
語法結構: execution([權限修飾符] [返回類型] [類全路徑] [方法名稱] ([參數列表]) )
例 1:對 com.atguigu.dao.BookDao 類里面的 add 進行增強
execution( * com.atguigu.dao.BookDao.add(…))
例 2:對 com.atguigu.dao.BookDao 類里面的所有的方法進行增強
execution( * com.atguigu.dao.BookDao. * (…))
例 3:對 com.atguigu.dao 包里面所有類,類里面所有方法進行增強
execution( * com.atguigu.dao. * . * (…))
AOP 操作(AspectJ 注解)
1、創建類,在類里面定義方法
User類:
package com.Keafmd.spring5.aopanno;import org.springframework.stereotype.Component;/*** Keafmd** @ClassName: User* @Description: 基于注解 被增強的類* @author: 牛哄哄的柯南* @date: 2021-01-18 13:54*/ @Component public class User {public void add(){ // int i = 10/0;System.out.println("add....");}}2、創建增強類(編寫增強邏輯),在增強類里面,創建方法,讓不同方法代表不同通知類型
UserProxy 類:
package com.Keafmd.spring5.aopanno;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component;/*** Keafmd** @ClassName: UserPtoxy* @Description: 增強類* @author: 牛哄哄的柯南* @date: 2021-01-18 13:56*/ @Component @Aspect //生成代理對象 @Order(3) public class UserProxy {//相同的切入點抽取@Pointcut(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void pointdemo(){}//前置通知//@Before注解就表示前置通知@Before(value = "pointdemo()")public void beafor(){System.out.println("before...");}//最終通知@After(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void after(){System.out.println("after...");}//后置通知(返回通知)@AfterReturning(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void afterReturning(){System.out.println("afterReturning...");}//異常執行@AfterThrowing(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void afterThrowing(){System.out.println("afterThrowing...");}//環繞通知@Around(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("around-before...");//被增強的方法執行proceedingJoinPoint.proceed();System.out.println("around-after...");}}3、進行通知的配置
(1)在 spring 配置文件中,開啟注解掃描
(2)使用注解創建 User 和 UserProxy 對象
(3)在增強類上面添加注解 @Aspect
(4)在 spring 配置文件中開啟生成代理對象
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: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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"><!--開啟注解掃描--><context:component-scan base-package="com.Keafmd.spring5.aopanno"></context:component-scan><!--開啟AspectJ生成代理對象--><aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>4、配置不同類型的通知
在增強類的里面,在作為通知方法上面添加通知類型注解,使用切入點表達式配置。
UserProxy 類:
package com.Keafmd.spring5.aopanno;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component;/*** Keafmd** @ClassName: UserPtoxy* @Description: 增強類* @author: 牛哄哄的柯南* @date: 2021-01-18 13:56*/ @Component @Aspect //生成代理對象 @Order(3) public class UserProxy {//相同的切入點抽取@Pointcut(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void pointdemo(){}//前置通知//@Before注解就表示前置通知@Before(value = "pointdemo()")public void beafor(){System.out.println("before...");}//最終通知@After(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void after(){System.out.println("after...");}//后置通知(返回通知)@AfterReturning(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void afterReturning(){System.out.println("afterReturning...");}//異常執行@AfterThrowing(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void afterThrowing(){System.out.println("afterThrowing...");}//環繞通知@Around(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("around-before...");//被增強的方法執行proceedingJoinPoint.proceed();System.out.println("around-after...");}}相同的切入點抽取
寫個方法然后調用這樣就可以把相同接入點抽取出來了。
//相同的切入點抽取@Pointcut(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void pointdemo(){}//前置通知//@Before注解就表示前置通知@Before(value = "pointdemo()")public void beafor(){System.out.println("before...");}有多個增強類多同一個方法進行增強,設置增強類優先級
在增強類上面添加注解 @Order(數字類型值),數字類型值越小優先級越高。
@Component @Aspect //生成代理對象 @Order(3) public class UserProxy {PersonProxy類:
package com.Keafmd.spring5.aopanno;import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component;/*** Keafmd** @ClassName: PersonProxy* @Description: 第二個增強類* @author: 牛哄哄的柯南* @date: 2021-01-18 14:39*/ @Component @Aspect @Order(1) //越小優先級越高 public class PersonProxy {//前置通知//@Before注解就表示前置通知@Before(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void beafor(){System.out.println("Person before...");}}通過@Order設置后PersonProxy 的前置通知就會比UserProxy 的前置通知先執行。
完全使用注解開發
創建配置類,這樣就不需要使用 xml 配置文件了。
ConfigAop類:
package com.Keafmd.spring5.config;import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.EnableAspectJAutoProxy;/*** Keafmd** @ClassName: ConfigAop* @Description: 配置類,完全注解,替代bean2.xml* @author: 牛哄哄的柯南* @date: 2021-01-18 15:12*/ @Configuration @ComponentScan(basePackages = {"com.Keafmd"}) //開啟注解掃描 @EnableAspectJAutoProxy(proxyTargetClass = true) //開啟AspectJ生成代理對象 public class ConfigAop { }代碼結構
測試代碼
測試代碼TestAop:
package com.Keafmd.spring5.test;import com.Keafmd.spring5.aopanno.User; import com.Keafmd.spring5.config.ConfigAop; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;/*** Keafmd** @ClassName: TestAop* @Description:* @author: 牛哄哄的柯南* @date: 2021-01-18 14:15*/ public class TestAop {@Testpublic void testAOPnno(){ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");User user = context.getBean("user",User.class);user.add();}//完全注解@Testpublic void testAOPnno2(){ApplicationContext context = new AnnotationConfigApplicationContext(ConfigAop.class);User user = context.getBean("user",User.class);user.add();} }輸出結果:
Person before... around-before... before... add.... around-after... after... afterReturning...Process finished with exit code 0testAOPnno和testAOPnno2的結果是相同的testAOPnno2采用是的完全注解開發,代替了xml配置文件。通過運行結果我們可以很輕清楚地看到不同類型通知的執行順序,以及增強類的優先級。
以上就是基于AspectJ實現AOP操作的全部內容。
看完如果對你有幫助,感謝點贊支持!
如果你是電腦端的話,看到右下角的 “一鍵三連” 了嗎,沒錯點它[哈哈]
加油!
共同努力!
Keafmd
總結
以上是生活随笔為你收集整理的Spring基于AspectJ实现AOP操作的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Scrapy爬虫:抓取大量斗图网站最新表
- 下一篇: 【opencv】颜色空间总结