Spring AOP的注解配置方式

版权声明:未经协商,禁止转载 https://blog.csdn.net/CHENFU_ZKK/article/details/82709384

AOP编程是编程中很重要的一部分,在开发中的地位和使用非常的重要和频繁,本人近期刚好接触到了在学习阶段很少使用的一种方式(也是基于注解的),故做一个随笔,用以加深印象
AOP(面向切面编程)
在软件行业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一个热点,也是春天框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
Aspectj
AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。
相关jar包下载地址:http://www.eclipse.org/aspectj/downloads.phphttp://mvnrepository.com/artifact/aspectj/aspectjweaver
如若地址变迁找不到也可以在这里下载:https://download.csdn.net/my
小案例地址:https://blog.csdn.net/CHENFU_ZKK/article/details/82709623

Spring对AOP的支持
Spring中AOP代理由Spring的IOC容器负责生成、管理,其依赖关系也由IOC容器负责管理。因此,AOP代理可以直接使用容器中的其它bean实例作为目标,这种关系可由IOC容器的依赖注入提供。Spring创建代理的规则为:
1、默认使用Java动态代理来创建AOP代理,这样就可以为任何接口实例创建代理了
2、当需要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理,也可强制使用CGLIB

AOP编程只需要程序员参与三个部分:
1、定义普通业务组件
2、定义切入点,一个切入点可能横切多个业务组件
3、定义增强处理,增强处理就是在AOP框架为普通业务组件织入的处理动作
所以进行AOP编程的关键就是定义切入点和定义增强处理,一旦定义了合适的切入点和增强处理,AOP框架将自动生成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注解

aspectJ的五种通知方式

全限定名org.aspectj.lang.annotation
1.@Before前置通知,在方法执行之前执行
String value(); String argNames() default "";
2.@After后置通知,在方法执行之后执行
String value();String argNames() default "";
3.@AfterReturning返回通知,在方法返回结果之后返回,可以访问方法的返回值,进行操作,例如写日志
String value() default "";String pointcut() default "";
String returning() default "";String argNames() default "";
4.@AfterThrowing异常通知,关联的方法若抛出异常,可以访问该异常,并进行操作
String value() default "";String pointcut() default "";
String throwing() default "";String argNames() default "";
5.@Around环绕通知,围绕着方法进行执行,上述四种的功能都能实现,其必须有返回值
String value(); String argNames() default "";

总结一下:上面的五种通知一共有四个类型的参数,其中argNames这个使用起来比较麻烦,不灵活,很少会使用到它,就是项目中有需要,也都是直接通过JoinPoint或者Proceedingjoinpoint对象直接来获取参数列表
这里写图片描述
而argNames使用起来就比较麻烦了,用法如下,而且还有一个小坑,可以自己尝试体验一下把args(x,y)的x和y参数位置互换,看方法内接受参数值的变化

@Around(
argNames = "x,y", value = "@annotation(com.romantic.aop.MyAop1Annotation)&&args(y,x)")
public Object method5(ProceedingJoinPoint joinPoint,int x, int y) {

配置切入点
直接在value属性内配置
在通知类型的Value属性上或者pointCut属性上内配置@annotation(自定义注解的全限定类名)
例如:value=”@annotation(com.romantic.aop.MyAop1Annotation)”
使用@poingCut注解配置
@pointcut(“execution(* com.romantic..(..))”)
private void pt() {}
在通知上直接配置该切入点
@After(value = “pt()”)
或者@pointcut(“@annotation(* com.romantic..(..))”)
当使用的是自定义注解配置切入点的时候,需要在被增强的方法上加入自定义的注解!!

在spring的配置文件内开启AOP的操作

<aop:aspectj-autoproxy proxy-target-class =true>

这里有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强。当配为true时,表示使用CGLIB动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring也将自动使用CGLIB动态代理。

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

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...

猜你喜欢

转载自blog.csdn.net/CHENFU_ZKK/article/details/82709384