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