javascript
Spring基于AspectJ实现AOP操作
基于AspectJ實(shí)現(xiàn)AOP操作
- 準(zhǔn)備工作
- 在項(xiàng)目工程里面引入 AOP 相關(guān)依賴。
- 如果是maven項(xiàng)目,使用pom.xml代替引入jar包的過程(注意)
- 學(xué)會(huì)使用切入點(diǎn)表達(dá)式
- AOP 操作(AspectJ 注解)
- 1、創(chuàng)建類,在類里面定義方法
- 2、創(chuàng)建增強(qiáng)類(編寫增強(qiáng)邏輯),在增強(qiáng)類里面,創(chuàng)建方法,讓不同方法代表不同通知類型
- 3、進(jìn)行通知的配置
- 4、配置不同類型的通知
- 相同的切入點(diǎn)抽取
- 有多個(gè)增強(qiáng)類多同一個(gè)方法進(jìn)行增強(qiáng),設(shè)置增強(qiáng)類優(yōu)先級(jí)
- 完全使用注解開發(fā)
- 代碼結(jié)構(gòu)
- 測試代碼
Spring 框架一般都是基于 AspectJ 實(shí)現(xiàn) AOP 操作。
需要注意的是:AspectJ 不是 Spring 組成部分,獨(dú)立 AOP 框架,一般把 AspectJ 和 Spirng 框架一起使用,進(jìn)行 AOP 操作。
基于 AspectJ 實(shí)現(xiàn) AOP 操作有兩種方式:
(1)基于 xml 配置文件實(shí)現(xiàn)
(2)基于注解方式實(shí)現(xiàn)(普遍使用)
準(zhǔn)備工作
在項(xiàng)目工程里面引入 AOP 相關(guān)依賴。
需要以下這些依賴:
如果是maven項(xiàng)目,使用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>學(xué)會(huì)使用切入點(diǎn)表達(dá)式
切入點(diǎn)表達(dá)式作用(通俗的講):知道對(duì)哪個(gè)類里面的哪個(gè)方法進(jìn)行增強(qiáng)。
語法結(jié)構(gòu): execution([權(quán)限修飾符] [返回類型] [類全路徑] [方法名稱] ([參數(shù)列表]) )
例 1:對(duì) com.atguigu.dao.BookDao 類里面的 add 進(jìn)行增強(qiáng)
execution( * com.atguigu.dao.BookDao.add(…))
例 2:對(duì) com.atguigu.dao.BookDao 類里面的所有的方法進(jìn)行增強(qiáng)
execution( * com.atguigu.dao.BookDao. * (…))
例 3:對(duì) com.atguigu.dao 包里面所有類,類里面所有方法進(jìn)行增強(qiáng)
execution( * com.atguigu.dao. * . * (…))
AOP 操作(AspectJ 注解)
1、創(chuàng)建類,在類里面定義方法
User類:
package com.Keafmd.spring5.aopanno;import org.springframework.stereotype.Component;/*** Keafmd** @ClassName: User* @Description: 基于注解 被增強(qiáng)的類* @author: 牛哄哄的柯南* @date: 2021-01-18 13:54*/ @Component public class User {public void add(){ // int i = 10/0;System.out.println("add....");}}2、創(chuàng)建增強(qiáng)類(編寫增強(qiáng)邏輯),在增強(qiáng)類里面,創(chuàng)建方法,讓不同方法代表不同通知類型
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: 增強(qiáng)類* @author: 牛哄哄的柯南* @date: 2021-01-18 13:56*/ @Component @Aspect //生成代理對(duì)象 @Order(3) public class UserProxy {//相同的切入點(diǎn)抽取@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...");}//異常執(zhí)行@AfterThrowing(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void afterThrowing(){System.out.println("afterThrowing...");}//環(huán)繞通知@Around(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("around-before...");//被增強(qiáng)的方法執(zhí)行proceedingJoinPoint.proceed();System.out.println("around-after...");}}3、進(jìn)行通知的配置
(1)在 spring 配置文件中,開啟注解掃描
(2)使用注解創(chuàng)建 User 和 UserProxy 對(duì)象
(3)在增強(qiáng)類上面添加注解 @Aspect
(4)在 spring 配置文件中開啟生成代理對(duì)象
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生成代理對(duì)象--><aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>4、配置不同類型的通知
在增強(qiáng)類的里面,在作為通知方法上面添加通知類型注解,使用切入點(diǎn)表達(dá)式配置。
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: 增強(qiáng)類* @author: 牛哄哄的柯南* @date: 2021-01-18 13:56*/ @Component @Aspect //生成代理對(duì)象 @Order(3) public class UserProxy {//相同的切入點(diǎn)抽取@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...");}//異常執(zhí)行@AfterThrowing(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void afterThrowing(){System.out.println("afterThrowing...");}//環(huán)繞通知@Around(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {System.out.println("around-before...");//被增強(qiáng)的方法執(zhí)行proceedingJoinPoint.proceed();System.out.println("around-after...");}}相同的切入點(diǎn)抽取
寫個(gè)方法然后調(diào)用這樣就可以把相同接入點(diǎn)抽取出來了。
//相同的切入點(diǎn)抽取@Pointcut(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void pointdemo(){}//前置通知//@Before注解就表示前置通知@Before(value = "pointdemo()")public void beafor(){System.out.println("before...");}有多個(gè)增強(qiáng)類多同一個(gè)方法進(jìn)行增強(qiáng),設(shè)置增強(qiáng)類優(yōu)先級(jí)
在增強(qiáng)類上面添加注解 @Order(數(shù)字類型值),數(shù)字類型值越小優(yōu)先級(jí)越高。
@Component @Aspect //生成代理對(duì)象 @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: 第二個(gè)增強(qiáng)類* @author: 牛哄哄的柯南* @date: 2021-01-18 14:39*/ @Component @Aspect @Order(1) //越小優(yōu)先級(jí)越高 public class PersonProxy {//前置通知//@Before注解就表示前置通知@Before(value = "execution(* com.Keafmd.spring5.aopanno.User.add(..))")public void beafor(){System.out.println("Person before...");}}通過@Order設(shè)置后PersonProxy 的前置通知就會(huì)比UserProxy 的前置通知先執(zhí)行。
完全使用注解開發(fā)
創(chuàng)建配置類,這樣就不需要使用 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生成代理對(duì)象 public class ConfigAop { }代碼結(jié)構(gòu)
測試代碼
測試代碼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();} }輸出結(jié)果:
Person before... around-before... before... add.... around-after... after... afterReturning...Process finished with exit code 0testAOPnno和testAOPnno2的結(jié)果是相同的testAOPnno2采用是的完全注解開發(fā),代替了xml配置文件。通過運(yùn)行結(jié)果我們可以很輕清楚地看到不同類型通知的執(zhí)行順序,以及增強(qiáng)類的優(yōu)先級(jí)。
以上就是基于AspectJ實(shí)現(xiàn)AOP操作的全部內(nèi)容。
看完如果對(duì)你有幫助,感謝點(diǎn)贊支持!
如果你是電腦端的話,看到右下角的 “一鍵三連” 了嗎,沒錯(cuò)點(diǎn)它[哈哈]
加油!
共同努力!
Keafmd
總結(jié)
以上是生活随笔為你收集整理的Spring基于AspectJ实现AOP操作的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Scrapy爬虫:抓取大量斗图网站最新表
- 下一篇: JavaScript判断当前浏览器是否为