一、什么是AOP
1.AOP为Aspect Oriented Programming的缩写,意为:面向 编程
2.通过【预编译方式】和【运行期动态代理】实现程序功能的统一维护的一种技术
3.在不修改目标类代码的前提下,可以通过AOP技术去增强目标类的功能。
4.利用AOP可以对业务代码中【业务逻辑】和【系统逻辑】进行隔离,从而使得【业务逻辑】和【系 统逻辑】之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
二、为什么使用AOP
1.AOP采取横向抽取机制 ,补充了 传统纵向继承机制(OOP)无法解决的重复性代码优化(性能监控、日志打印、事物管理),将业务逻辑和系统处理的代码(关闭连接、事务管理、操作日志记录)解耦。
2.重复性代码被抽取出来之后,可以在改原有代码前提下,可以动态横向添加共性代码,增加功能。
三、相关术语
- 连接点(Joinpoint) 程序执行的某个特定位置,如某个方法调用前,调用后,方法抛出异常后,这些代码中的特定点称为连接点。简单来说,就是在哪加入你的逻辑增强
连接点表示具体要拦截的方法,上面切点是定义一个范围,而连接点是具体到某个方法- 切点(PointCut) 每个程序的连接点有多个,如何定位到某个感兴趣的连接点,就需要通过切点来定位。比如,连接点--数据库的记录,切点--查询条件
切点用于来限定Spring-AOP启动的范围,通常我们采用表达式的方式来设置,所以关键词是范围- 增强(Advice) 增强是织入到目标类连接点上的一段程序代码。在Spring中,像BeforeAdvice等还带有方位信息
通知是直译过来的结果,我个人感觉叫做“业务增强”更合适 对照代码就是拦截器定义的相关方法,通知分为如下几种:
前置通知(before):在执行业务代码前做些操作,比如获取连接对象
后置通知(after):在执行业务代码后做些操作,无论是否发生异常,它都会执行,比如关闭连接对象
异常通知(afterThrowing):在执行业务代码后出现异常,需要做的操作,比如回滚事务
返回通知(afterReturning),在执行业务代码后无异常,会执行的操作
环绕通知(around),这个目前跟我们谈论的事务没有对应的操作,所以暂时不谈- 目标对象(Target) 需要被加强的业务对象
- 织入(Weaving) 织入就是将增强添加到对目标类具体连接点上的过程。
织入是一个形象的说法,具体来说,就是生成代理对象并将切面内容融入到业务流程的过程。- 代理类(Proxy) 一个类被AOP织入增强后,就产生了一个代理类。
- 切面(Aspect) 切面由切点和增强组成,它既包括了横切逻辑的定义,也包括了连接点的定义,SpringAOP就是将切面所定义的横切逻辑织入到切面所制定的连接点中。
二、AOP实现方式----JDK(默认)和CGLIB
1、JDK生成代理对象
JDK动态代理是通过接口的形式实现的,即代理类和目标类同时实现同一个接口即可。
JDK动态代理是通过帮我们新建代理类,通过JDK加载生成对应的.class文件,加载到JVM内存中,并生成动态代理对象。
2、CGLIB生成代理类
CGLIB是通过继承的形式实现动态代理的,可以实现非final类均可以实现动态代理。
CGLIB通过ASM框架复制原有类的.class文件,并修改字节码从而生成代理类,再加载到JVM内存中生成动态代理对象
3、JDK和CGLIB动态代理执行流程
4、JDK动态代理和CGLIB动态代理的区别和联系
1.JDK动态代理是Java自带的,cglib动态代理是第三方jar包提供的。
2.JDK动态代理是针对拥有接口的目标类进行动态代理的,而Cglib是非final类都可以进行动态代理。 但是Spring优先使用JDK动态代理。
3.JDK动态代理实现的逻辑是目标类和代理类都实现同一个接口,目标类和代理类是平级的。而Cglib动 态代理实现的逻辑是给目标类生个孩子(子类,也就是代理类),目标类和代理类是父子继承关系。
4.JDK动态代理在早期的JDK1.6左右性能比cglib差,但是在JDK1.8以后cglib和jdk的动态代理性能 基本上差不多。反而jdk动态代理性能更加的优越。
5.JDK动态代理是通过帮我们新建代理类,通过JDK加载生成对应的.class文件,加载到JVM内存中,并生成动态代理对象;而CGLIB则是通过ASM框架复制原有类的.class文件,并修改字节码从而生成代理类,再加载到JVM内存中生成动态代理对象。