spring aop (上) aop概念、使用、动态代理原理

时间:2022-06-23
本文章向大家介绍spring aop (上) aop概念、使用、动态代理原理,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

参考

思路

我们要弄明白,spring aop是什么?怎么用?实现原理?

spring aop是什么

参考Spring AOP详细介绍 AOP(Aspect Oriented Programming)面向切面编程。面向切面,是与OOP(Object Oriented Programming)面向对象编程并列的编程思想。 通过定义切面,可以让一些业务无关的代码,与业务代码相解耦。比如要在业务方法执行前后打印日志时,我们只需定义一个切面,而不用把打印日志的代码加到业务方法中,这样就将日志打印代码和业务代码相解耦了。 它有几个概念:Aspect(切面)、JointPoint(连接点)、Advice(通知)、Pointcut(切入点)、AOP代理。概念的详细解释见Spring - 通知(Advice)和Advisor(增强器/顾问)Spring AOP详细介绍。 切面有两种实现:Advice(通知)、Advisor(增强器)。两种实现的区别其实都是将通知和切面进行了封装,原理基本上是一样的,只是使用的方式不同而已。详情可参考<aop:aspect>与<aop:advisor>的区别

来自https://blog.csdn.net/q982151756/article/details/80513340

spring aop 使用

spring aop的切面有两种声明方式:xml、注解。任何一种声明方式下,你都可以定义Advice和Advisor。 一般人们喜欢用Advice做功能增强,用Advisor做事务管理。 要进一步了解,可参考[1]

spring aop 通知流程

下图展示了spring aop在方法正常返回和抛出异常时,各个通知的执行顺序。

spring aop的实现原理

jdk动态代理与CGLib动态代理的区别

参考:

  1. jdk动态代理与CGLib的区别 举例说明了jdk和cglib实现动态代理的雏形。
  2. 动态代理:JDK动态代理和CGLIB代理的区别

spring aop是用动态代理实现的。通过动态代理,可以对被代理对象的方法进行增强。 spring aop用到了两种动态代理技术:jdk动态代理、cglib库。

  • JDK动态代理只能对实现了接口的类生成代理,而不能针对类。
  • CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法(继承)。

在用jdk动态代理对某个对象的方法增强时,这个方法一定要是实现自某个接口。jdk会生成一个继承该接口的代理对象,从而将代理对象上的接口方法调用都移交给InvocationHandler.invoke。打个比方,假设有类关系如下:

上图中,我们可以用jdk动态代理对Student.say进行功能增强,但没法增强Student.walk。

我们可以用jdk动态代理在Student.say方法调用前后打印日志,因为Student.say继承自Person.say。jdk动态代理会生成Person接口的实现类对象,将其上的say方法调用都移交给InvocationHandler.invoke。 但是,如果我们想对Student.walk增强,jdk动态代理就束手无策了。因为Student.walk方法不来自任何一个接口。就算我们生成了一个Person的实现类对象,它也无法调用walk方法,因为Person接口没有walk方法。而cglib可以做到这一点。cglib会生成一个继承Student类的代理对象,所有代理对象上调用的方法,都会移交给MethodInterceptor.intercept执行,进而我们可以对这个类里的所有方法进行功能增强(final方法除外,因为不能final方法被继承)。 所以,当要增强没有实现任何接口的方法时,Spring是使用CGlib实现的。

springaop的具体实现原理

事务管理开启时 全局视角


  1. 各种@Before、@Around等方法只能用在Bean的方法上?因为这样,通过@Autowired注入时,才能进行代理设置。

  1. 有几个特点,读者可以记着。1. @PointCut注解的方法只需要是空方法。不会被执行。2. 要学习AspectJ切点表达式。3. @Around的功能较多,使用也更频繁。4. 如果感兴趣,可以研究@Around中的jointpoint.proceed()方法 5. 各种@Before、@Around等方法只有在对象是被以Bean注入的时候才有效。因为这样,通过@Autowired注入时,spring aop才能为原对象创建代理对象。