一、背景
AOP不是Spring特有的一种能力,AOP是计算机技术中一种编程思想,是在OOP之后的又一编程经验总结,能无侵入地、批量地加工现有逻辑,对程序设计而言是个极其好用的手段。
AOP的实现有众多方式,Spring AOP只是其中一种,这一点眼界要有,不要以为Spring AOP就是全部,各个语言都有AOP的使用。
Spring AOP是通过动态代理方式实现的,动态代理是有其明显的特点的,比如多次代理后方法执行的时序,同一个类型里方法嵌套调用等,这一点会在动态代理里详细说明。所以在Spring的类设计体系中,会有很多Proxy后缀的命名。
概念
AOP是“面向方面编程”,要解决的问题是,把重复性的横切逻辑独立出来,然后融合到业务逻辑中,达到和原来一样的业务流程;
AOP的工作重心在于如何将增强应用于目标对象的连接点上。这里包括两项工作:
- 第一、如何通过切点和增强定位到连接点上:
- 第二、如何在增强中编写切面的代码。
1、切点(Pointcut)
切点是一组规则,用来定义程序代码哪些地方将会被切,实际运行时产生被切的地方就是连接点。
切点和连接点不是一对一的关系,一个切点可以匹配多个连接点。
在Spring中,切点通过org.springframework.aop.Pointcut 接口进行描述,它使用类和方法作为连接点的查询条件,SpringAOP的规则解析引擎负责解析切点所设定的查询条件,找到对应的连接点。
2、连接点(Joinpoint)
在Spring中,使用org.aspectj.lang.JoinPoint来描述连接点,可以从连接点获取被切的方法签名和实参等信息。
连接点是可以插入横切逻辑的地方,它是一个静态定义,描述的可切入点的分类,例如方法调用、异常抛出等。同时它又能在运行时能用来表达具体被切的点,比如a()方法被增强了,我们可以说a()方法是一个连接点。
连接点和切点有密切关系,切点是一组用来筛选连接点的规则。其实切点这个词并不太准确,如果是我命名,我会将切点命名为筛选点。
3、增强(Advice)
增强是织入目标类连接点上的一段程序代码,在Spring中,增强除用于描述一段程序代码外, 还拥有另一个和连接点相关的信息,这便是执行点的方位。结合执行点的方位信息和切点信息,就可以找到特定的连接。
正因为增强既包含用于添加到目标连接点上的一段执行逻辑, 又包含用于定位连接点的方位信息,所以Spring 所提供的增强接口都是带方位名的,如BeforeAdvice 、AfterReturningAdvice、ThrowsAdvice 等。
BeforeAdvice 表示方法调用前的位置,而AferRetunningAdvice表示访问返回后的位置。所以只有结合切点和增强,才能确定特定的连接点并实施增强逻辑。
4、顾问(advisor)
advisor是Pointcut和advice的组合。
5、目标对象(Target)
目标对象可以理解为业务逻辑,增强逻辑的织入目标类,如果没有AOP,那么业务逻辑需要完成业务逻辑+所有非横切逻辑;
6、引介(Introduction)
引介是一种特殊的增强,它为类添加一些属性和方法。这样,即使一个业务类原本没有实现某个接口,通过AOP的引介功能,也可以动态地为该业务类添加接口的实现逻辑,让业务类成为这个接口的实现类。
7、织入(Weaving)
织入是将增强添加到目标类的具体连接点上的过程。AOP就像一- 台织布机,将目标类、增强或者引介天衣无缝地编织到- -起。我们不能不说“织入”这个词太精辟了。
根据不同的实现技术,AOP有3种织入方式:
- (1)编译期织入,这要求使用特殊的JAVA编译器。
- (2)类装载期织入,这要求使用特殊的类装载器。
- (3)动态代理织入,在运行期为目标类添加增强生成子类的方式。
Spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入。
8、代理(Proxy)
一个类被AOP织入增强后,就产生了一个结果类,它是融合了原类和增强逻辑的代理类。
根据不同的代理方式,代理类既可能是和原类具有相同接口的类,也可能就是原类的子类,所以可以采用与调用原类相同的方式调用代理类。
9、切面(Aspect)
切面由切点和增强(引介)组成,它既包括横切逻辑的定义,也包括连接点的定义。
10、AOP和代理的关系
代理需要包含aop的信息,这样生成的代理才具备aop能力。
代理是一种设计模式,实现方式有多种,静态代理和动态代理,Spring AOP采用的是动态代理,是在运行时生成代理对象。动态代理又分为jdk proxy和cglib proxy。
切面是批量修改代码行为,结合代理实现就是批量生成代理对象。所以程序员写Advice和Pointcut给proxy,proxy动态生成对象替换原生对象,实现aop功能。
aop设计哲学:
Pointcut,Advice,JoinPoint
Spring AOP设计哲学:
org.springframework.aop.framework.ProxyFactory 生成代理的工厂,上层应用类
org.springframework.aop.framework.ProxyCreatorSupport 下层实现类
proxy 设计哲学:
org.springframework.aop.framework.AopProxy
org.springframework.aop.framework.JdkDynamicAopProxy
org.springframework.aop.framework.CglibAopProxy
jdk proxy设计哲学:
cglib proxy设计哲学:
总结
对于切面使用者来说,需要关心的就是Pointcut和Advice,Pointcut扫描出所有要处理的地方,Advice定义切入逻辑,这2个就可以满足几乎所有切面使用者的需求。其他的概念几乎都是实现层面的概念,是深入理解切面才需要了解的。