spring——基于注解的AspectJ AOP开发(转载)
2022/4/23 14:12:46
本文主要是介绍spring——基于注解的AspectJ AOP开发(转载),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
在 Spring 中,虽然我们可以使用 XML 配置文件可以实现 AOP 开发,但如果所有的配置都集中在 XML 配置文件中,就势必会造成 XML 配置文件过于臃肿,从而给维护和升级带来一定困难。
为此,AspectJ 框架为 AOP 开发提供了一套 @AspectJ 注解。它允许我们直接在 Java 类中通过注解的方式对切面(Aspect)、切入点(Pointcut)和增强(Advice)进行定义,Spring 框架可以根据这些注解生成 AOP 代理。
关于注解的介绍如表 1 所示。
名称 | 说明 |
---|---|
@Aspect | 用于定义一个切面。 |
@Pointcut | 用于定义一个切入点。 |
@Before | 用于定义前置通知,相当于 BeforeAdvice。 |
@AfterReturning | 用于定义后置通知,相当于 AfterReturningAdvice。 |
@Around | 用于定义环绕通知,相当于 MethodInterceptor。 |
@AfterThrowing | 用于定义抛出通知,相当于 ThrowAdvice。 |
@After | 用于定义最终通知,不管是否异常,该通知都会执行。 |
@DeclareParents | 用于定义引介通知,相当于 IntroductionInterceptor(不要求掌握)。 |
启用 @AspectJ 注解支持
在使用 @AspectJ 注解进行 AOP 开发前,首先我们要先启用 @AspectJ 注解支持。
我们可以通过以下 2 种方式来启用 @AspectJ 注解。
1)使用 Java 配置类启用
我们可以在 Java 配置类(标注了 @Configuration 注解的类)中,使用 @EnableAspectJAutoProxy 和 @ComponentScan 注解启用 @AspectJ 注解支持。
定义通知
AspectJ 为我们提供了以下 6 个注解,来定义 6 种不同类型的通知(Advice),如下表。
注解 | 说明 |
---|---|
@Before | 用于定义前置通知,相当于 BeforeAdvice。 |
@AfterReturning | 用于定义后置通知,相当于 AfterReturningAdvice。 |
@Around | 用于定义环绕通知,相当于 MethodInterceptor。 |
@AfterThrowing | 用于定义抛出通知,相当于 ThrowAdvice。 |
@After | 用于定义最终通知,不管是否异常,该通知都会执行。 |
@DeclareParents | 用于定义引介通知,相当于 IntroductionInterceptor(不要求掌握)。 |
以上这些通知注解中都有一个 value 属性,这个 value 属性的取值就是这些通知(Advice)作用的切点(PointCut),它既可以是切入点表达式,也可以是切入点的引用(切入点对应的方法名称),示例代码如下。
示例
下面,我们就通过一个完整的实例,来演示下如何通过注解的方式实现 AspectJ AOP 开发。
1. 新建一个名为 my-spring-asepctj-demo2 的 Java 项目,并将以下依赖 Jar 包导入到该项目中。
- commons-logging-1.2.jar
- spring-aop-5.3.13.jar
- spring-aspects-5.3.13.jar
- spring-beans-5.3.13.jar
- spring-context-5.3.13.jar
- spring-core-5.3.13.jar
- spring-expression-5.3.13.jar
- aspectjweaver-1.9.7.jar
2. 在 net.biancheng.c.dao 包下,创建一个名为 UserDao 的接口,代码如下。
5. 在 net.biancheng.c 包下,创建一个名为 MyAspect 的切面类,代码如下。
package net.biancheng.c; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component // 定义成 Bean @Aspect //定义为切面 public class MyAspect { @Before("execution(* net.biancheng.c.dao.UserDao.add(..))") public void before(JoinPoint joinPoint) { System.out.println("前置增强……" + joinPoint); } @After("execution(* net.biancheng.c.dao.UserDao.get(..))") public void after(JoinPoint joinPoint) { System.out.println("最终增强……" + joinPoint); } /** * 将 net.biancheng.c.dao包下的 UserDao 类中的 get() 方法 定义为一个切点 */ @Pointcut(value = "execution(* net.biancheng.c.dao.UserDao.get(..))") public void pointCut1() { } /** * 将 net.biancheng.c.dao包下的 UserDao 类中的 delete() 方法 定义为一个切点 */ @Pointcut(value = "execution(* net.biancheng.c.dao.UserDao.delete(..))") public void pointCut2() { } //使用切入点引用 @Around("MyAspect.pointCut2()") public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("环绕增强……1"); proceedingJoinPoint.proceed(); System.out.println("环绕增强……2"); } //使用切入点表达式 @AfterReturning(value = "execution(* net.biancheng.c.dao.UserDao.modify(..))", returning = "returnValue") public void afterReturning(Object returnValue) { System.out.println("后置返回增强……,方法返回值为:" + returnValue); } }
这篇关于spring——基于注解的AspectJ AOP开发(转载)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26JAVA语音识别项目资料的收集与应用
- 2024-11-26Java语音识别项目资料:入门级教程与实战指南
- 2024-11-26SpringAI:Java 开发的智能新利器
- 2024-11-26Java云原生资料:新手入门教程与实战指南
- 2024-11-26JAVA云原生资料入门教程
- 2024-11-26Mybatis官方生成器资料详解与应用教程
- 2024-11-26Mybatis一级缓存资料详解与实战教程
- 2024-11-26Mybatis一级缓存资料详解:新手快速入门
- 2024-11-26SpringBoot3+JDK17搭建后端资料详尽教程
- 2024-11-26Springboot单体架构搭建资料:新手入门教程