Spring AOP的注解配置方式

本文深入探讨了AOP(面向切面编程)的核心概念和技术,包括AOP在开发中的重要性和使用频率,AspectJ框架的介绍及五种通知方式,Spring框架对AOP的支持和实战配置,以及AOP编程的基本步骤和执行顺序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AOP编程是编程中很重要的一部分,在开发中的地位和使用非常的重要和频繁,在各个技术的源码中也是频频出现,因此很有必要对此知识多加学习

AOP:面向切面编程

AOP是通过预编译方式或运行期动态代理实现程序功能的统一维护的一种技术,利用AOP可以对业务逻辑进行横向抽取,从而使得业务逻辑各部分之间的耦合度降低并提高代码的可重用性,提高开发效率。

Aspectj

AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,并且它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。
相关jar包下载地址:aspectj | aspectjweaver
楼主上传的资源地址:优快云
案例地址:Spring-AOP

AspectJ的五种通知方式

org.aspectj.lang.annotation包下

注解名称作用域
@Before前置通知在方法执行之前执行
@After后置通知在方法执行之后执行
@AfterReturning返回通知在方法返回结果之后返回,可以访问方法的返回值,进行操作,例如写日志
@AfterThrowing异常通知关联的方法若抛出异常,可以访问该异常,并进行操作
@Around环绕通知围绕着方法进行执行,上述四种的功能都能实现,其必须有返回值

@Before属性

  • String value();
  • String argNames() default “”;

@After属性

  • String value();
  • String argNames() default “”;

@AfterReturning属性

  • String value() default “”;
  • String pointcut() default “”;
  • String returning() default “”;
  • String argNames() default “”;

@AfterThrowing属性

  • String value() default “”;
  • String pointcut() default “”;
  • String throwing() default “”;
  • String argNames() default “”;

@Around属性

  • String value();
  • String argNames() default “”;

上面的五种通知一共有四个类型的参数,就楼主的使用情况来看【在Spring框架中使用】argNames起来比较麻烦,不灵活,很少会使用到它,如有获取代理对象方法入参的需求,也可以通过JoinPoint或者Proceedingjoinpoint对象直接来获取入参列表

Spring对AOP的支持

Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则为:

  1. 默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了。
  2. 当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB。
Proceedingjoinpoint对象

Proceedingjoinpoint 继承了 JoinPoint 。是在JoinPoint的基础上暴露出 proceed 这个方法。proceed很重要,这个是aop代理链执行的方法,暴露出这个方法,就能支持 aop:around 这种切面(而其他的几种切面只需要用到JoinPoint,这跟切面类型有关)
Proceedingjoinpoint 可以修改被代理的方法的参数和最终的返回值,JoinPoint 则没有这么强大。

AOP编程步骤

AOP编程只需要程序员参与三个部分:

  1. 定义普通业务组件
  2. 定义切入点,一个切入点可能横切多个业务组件
  3. 定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作

综上所述进行AOP编程的关键就是定义切入点定义增强处理,一旦定义了合适的切入点和增强处理,AOP框架将自动生成AOP代理。即:代理对象的方法=增强处理+被代理对象的方法。

Spring AOP 实战

导入依赖:
<!-- 必然需要的是spring的aop jar包(导入spring-context的时候会自动加入此包,因此也可以不加入) -->
<dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.3.8.RELEASE</version>
</dependency>
<!-- aspectJ的核心jar包 -->
<dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.10</version>
</dependency>
<dependency>
           <groupId>org.aspectj</groupId>
           <artifactId>aspectjrt</artifactId>
           <version>1.8.10</version>
</dependency>
配置切面类

切面类开发完毕后在类名上加上@Aspect注解,表示该类是切面类。

配置切入点

1.自定义注解作为切入点

//@annotation(自定义注解的全限定类名)
//例如:
value="@annotation(com.romantic.aop.MyAop1Annotation)"

2.使用切入点表达式匹配

@pointcut("execution(* com.romantic.*.*(..))")
private void pt() {}
在spring的配置文件内开启AOP的操作
<aop:aspectj-autoproxy proxy-target-class =true>
  • proxy-target-class
    该值默认为false,表示使用jdk动态代理织入增强。当配为true时,表示使用CGLIB动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,Spring也将自动使用CGLIB动态代理。

AOP的执行顺序

以下结果均经本人验证,仅供参考

一个AOP的执行顺序
aroundAdvice...start
beforeAdvice...
被增强方法...
aroundAdvice...end
afterAdvice...
afterReturnAdvice...

有异常的执行顺序
aroundAdvice...start
beforeAdvice...
被增强的方法[异常产生之前]...
afterAdvice...
afterthrowAdvice...

多个AOP的执行顺序配置有三种方式

  1. 切面类实现org.springframework.core.Ordered接口
  2. 使用注解@Order(number)
  3. 使用xml配置文件配置,配置如下
<aop:config expose-proxy="true">  
    <aop:aspect ref="aopBean" order="0">    
     .......    
    </aop:aspect>    
</aop:config>

多个AOP的执行顺序:

整体上看Order值小的AOP先执行,但是,如果只看后置(after类型)增强或者afterReturn类型的,就是Order值大的AOP的先执行,这点容易绕晕,画个图来说明一下(以同心圆为例)
这里写图片描述

以下输出结果均经本人验证,仅供参考

aroundAdvice...start
beforeAdvice...
aroundAdvice222...start
beforeAdvice222...
被增强方法...
aroundAdvice222...end
afterAdvice222...
afterReturnAdvice222...
aroundAdvice...end
afterAdvice...
afterReturnAdvice...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值