spring aop (上) aop概念、使用、动态代理原理
参考
- Spring Boot (教程十二: AOP拦截器) 举例不错
- Spring AOP(一) AOP基本概念
- @Around简单使用示例——SpringAOP增强处理
- Spring aop的实现原理 通过jdk动态代理,能实现目标代码、代理对象与增强功能的代码的解耦。
- 《Spring设计思想》AOP设计基本原理和《Spring设计思想》AOP实现原理(基于JDK和基于CGLIB) springaop一文通
思路
我们要弄明白,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动态代理的区别
参考:
- jdk动态代理与CGLib的区别 举例说明了jdk和cglib实现动态代理的雏形。
- 动态代理: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的具体实现原理
事务管理开启时 全局视角
- 各种@Before、@Around等方法只能用在Bean的方法上?因为这样,通过
@Autowired
注入时,才能进行代理设置。
- 有几个特点,读者可以记着。1. @PointCut注解的方法只需要是空方法。不会被执行。2. 要学习AspectJ切点表达式。3. @Around的功能较多,使用也更频繁。4. 如果感兴趣,可以研究@Around中的jointpoint.proceed()方法 5. 各种@Before、@Around等方法只有在对象是被以Bean注入的时候才有效。因为这样,通过
@Autowired
注入时,spring aop才能为原对象创建代理对象。 ↩
- OpenCV中BLOB特征提取与几何形状分类
- OpenCV实现照片自动红眼去除
- OpenCV3.1.0级联分类器训练与使用
- 图像处理之理解Homography matrix(单应性矩阵)
- OpenCV中图像直方图与应用
- OpenCV中图像修复技术介绍与演示
- 44个Java代码性能优化总结
- LDA(Linear Discriminant Analysis)算法介绍
- Express.js 4,Node.js,MongoDB REST API 简易教程
- 基于梯度下降算法求解线性回归
- 彩色图像高斯反向投影
- OpenCV中直方图反向投影算法详解与实现
- 基于一维级联快速膨胀与腐蚀算法
- mac下利用Breakpad的dump文件进行调试
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释