spring-aop(一)学习笔记
AOP(Aspect-Oriented Programming)
- 面向切面编程
- 将复杂的需求分解出不同方面,将散布在系统中的公共功能集中解决
- 面向切面编程,是一种通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态添加功能的技术
使用“横切”技术,AOP把软件系统分为两部分
- 核心关注点
- 横切关注点
实现方法:动态代理设计模式
AOP相关术语
- 增强(Advice)
- 切入点(Pointcut)
- 连接点(Joinpoint)
- 切面(Aspect)增强(Advice)和切入点(Pointcut)的组合
- 代理(Proxy)
- 目标对象(Target)
- 织入(Weaving)是指实现切面的过程
Aop的实现者
- AspectJ
- Jboss Aop
- Spring Aop 依赖了AspectJ
Spring提供了4种实现Aop的方式
- 基于代理的经典Aop 在老版本中存在通过代理工厂实现的,现在基本不用了
- 纯POJO 通过引入schema文档,把一个普通的java bean配置成切面
- @ApectJ注解驱动的切面
- 注入式AspectJ切面 spring只能对普通方法实现增强,构造方法和属性是不允许的,特殊情况下可以使用AspectJ
表达式匹配规则
public * addUser(com.pb.entity.User): "*"表示匹配所有类型的返回值
public void (com.pb.entity.User) : ""表示匹配所有方法名
public void addUser (..) : ".. "表示匹配所有参数个数和类型
* com.pb.service..(..) : 匹配com.pb.service包下所有类的所有方法
* com.pb.service..*(..) 匹配com.pb.service包及子包下所有类的所有方法
使用Aop实现日志的输出
- 在applicationContext.xml中引入schema文件
- 定义日志模块类,方法
导入Aop所需的jar文件
spring-aop-5.2.9.RELEASE.jar spring自己支持aop的jar包
aspectjweaver-1.9.6.jar spring依赖aspectj框架的jar文件
aopalliance-1.0.jar Aop Aliance是 AOP的接口标准,定义了AOP中的基础概念(Advice,CutPoint,Advisor等),为各种AOP实现提供统一的接口。Spring AOP,GUICE都采用了AOP Alliance标准,所以需要导入aopalliance.jar,但是在Spring4.3之后内置了AOP alliance接口,不再需要单独引入aopalliance.jar
spring-aspects-5.2.9.RELEASE.jar Spring ships with a small AspectJ aspect library,一个小型的AspectJ的库
- 编写配置文件
- 声明目标类(需要增强的类的方法)
- 配置切面
- 声明切入点
- 织入(指定增强方法bean的id,指明切入点,声明织入的方法类型及方法)
- 运行程序查看结果
在日志输出时,这样输出是不行的,因为我们不知道是哪个类的哪个方法输出的,还有就是在权限控制中我们要判断参数是否安全,这时必须要获取连接点的信息,也就是需要增强的方法的信息,如:所属类,方法名及参数等。那么应该怎么实现呢?
- 修改日志类,在增强的方法中传入参数JoinPoint jp
- 如需获取增强的目标方法的返回值,就需要在后置增强中配置returning,指明返回信息的接收对象,然后在后置增强的方法中把接收对象传入进来
- 接着,再来看下运行结果
- 如需获取增强的目标方法的返回值,就需要在后置增强中配置returning,指明返回信息的接收对象,然后在后置增强的方法中把接收对象传入进来
JDK 动态代理是通过接口来实现的,面向接口的代理
CGLib 面向类的代理,在运行过程中动态创建子类来进行代理,创建速度慢,执行速度快,会受到final修饰符限制,final修饰的方法和属性不能代理
Spring 会根据情况自动选择代理,如:
在aop:config上设置proxy-target-class="true"为CGlib代理
参考资料:
https://zhuanlan.zhihu.com/p/24565766
https://blog.csdn.net/pingnanlee/article/details/38845955