目录
动态代理:
JDK动态代理
CGLIB动态代理
JDK动态代理实现步骤:
AOP(Aspect Orient Programming面向切面编程)
术语:
切面三要素:
AOP的实现:
AspectJ框架的使用:
使用AspectJ实现AOP的基本步骤:
JoinPoint使用
@AfterReturning
@Around
@AfterThrow
@After
@PointCut
动态代理是指。程序在整个运行过程中根本就不存在目标类的代理类。目标对象的代理对象只是由代理生成工具(不是真实定义的类)在程序运行时由JVM根据反射等机制动态生成的。代理对象与目标对象的代理关系在程序运行时才确立。
动态代理的作用:
1)在日标类源代码不改变的情况下,增加功能.
2)减少代码的重复
3)专注业务逻辑代码
4)解耦合,让你的业务功能和日志,事务非业务功能分离。
场景案例:
开发多年的老项目,需要在部分执行代码中加入一些新功能:
按照正常思路应该为:创建一个服务类,然后放到之前的代码要执行的位置。
动态代理的实现方式常用的有两种:使用JDK的Proxy,与通过CGLIB生成代理。Jdk的动态要求目标对象必须实现接口,这是java 设计上的要求。从jdk1.3以来。java 语言通过jawa.lang.eflect包提供三个类支持代理模式Proxy, Method 和InowcationHandler.
CGLIB(Code Generation Library)是一个开源项目.是一个强大的.高性能,高质量的Code生成类库,它可以在运行期扩展Java 类与实现Java接口.它广泛的被许多AOP 的框架使用。例如Spring AOP.
使用JDK的Proxy 实现代理,要求目标类与代理类实现相同的接口。若目标类不存在接口,则无法使用该方式实现。但对于无接口的类,要为其创建动态代理。就要使用CGUB8来实现。
CGLIB代理的生成原理:生成目标类的子类。而子类是增强过的,这个子类对象就是代理对象。所以,使用CGLIB生成动态代理,要求目标类必须能够被继承,即不能是final 的类。
CGLIB经常被应用在框架中,例如Spring . Hibernate 等. cgib的代理效率高于Jdk.项目中直接使用动态代理的地方不多。一般都使用概架提供的功能。
2.创建InvocationHandler接口的实现类,在这个类实现给目标方法增加功能。
3.使用jdk中类Proxy ,创建代理对象。实现创建对象的能力。
切面:在原有的功能上增加的新功能。 切面的特点:一般是非业务方法,可以独立使用。(日志打印、功能时间统计等)
面向切面编程的整体思路:1、分析该项目中哪些可以通过切面解决的问题 2、需要在什么时候执行,方法调用前还是调用后3合理安排切面执行的位置,在哪个类,那个方法增加增强功能。
实现方式:
基于动代理的,可以使用jdk、 oglib两种代理方式.
Aop就是动态代理的规范化,把动态代理的实现步骤、方式都定义好了,让开发人员用一神种统一的方式使用。
切面有三个美健的要素:
1)切面的功能代码,切面干什幺
2)切面的执行位置,使用Pointeut表示切面执行位置.
3)切面的抉行时间,使用Advice表示时间,在目标方法之前,还是目标方法之后
AOP是一个规范,是动态代理的一个规范化使用
AOP技术实现框架:
1、spring:spring在内部实现了AOP规范。spring主要在事务处理时使用aop;(但是在项目中很少用,因为比较笨重)
2、AspectJ:一个开源的框架(是开发过程中的主要手段),spring框架中集成了aspectJ,框架,通过spring可以直接使用。使用方式 :
(1)使用xml配置文件配置全局事务。
(2)使用注解,我们在项目中要做aop功能,一般都是用注解,aspectJ有5个注解
在aspectk乱加中使用注解标识
(1)@Before
(2)@AfterReturning
(3)@Around
(4)@AfterThrowing
(5)@After
2、标识切面执行的位置,使用的是切入点表达式
3、使用举例
1、新建maven项目
2、加入依赖
3、创建目标类:接口和他的实现类
要做的是给类中的方法增加功能
4、创建切面类:普通类
5、创建spring的配置文件,声明对象,把对象交给容器统一管理,生命对象你可以使用注解或者xml配置文件
6、创建测试类,从spring容器中获取目标对象(实际就是代理对象)。
通过代理执行方法,实现aop的功能增强。
举例:
1、创建切面类
2、创建spring的配置文件,声明对象
当扫描到
JoinPoint:要加入切面功能的业务方法。
作用:可以在通知方法中获取方法执行时的信息,例如:方法名称、方法实参
注意,这里的参数res就是切面方法的返回值。
使用场景:根据连接点方法确定是否执行某些动作
1、在对结果进行修改之后,是会对最后的结果造成影响的。相当于把原函数替换了。
2、环绕通知经常做事物,在目标方法之前开启事物,执行目标方法,在目标方法后提交事物
异常通知
最终通知