1.AOP概述:Aspect Oriented Programing 面向切面编程
AOP术语:
连接点:用方法表示的程序执行点+相对点的方位,(注:spring仅支持方法的连接点,即只能在方法调用前、方法调用后、方法抛出异常以及方法调用前后这些程序执行点织入增强)
切点(Pointcut):切点只定位到某个方法(方法表示的程序执行点 )上,如想定位到具体连接点上,还需要提供方位信息
增强(Advice):包含用于添加到目标连接点上的一段执行逻辑+用于定位连接点的方位信息
目标对象(Target):增强逻辑的织入目标类
引介:是一种特殊的增强,它为类添加一些属性和方法
织入:将增强添加到目标类具体连接点上的过程。AOP有三种织入的方式:
1>编译期织入,这要求使用特殊的Java编译器
2>类装载期织入,这要求使用特殊的类装载器
3>动态代理织入,在运行期为目标类添加增强生成之类的方式
Spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入
代理(Proxy):一个类被AOP增强后产出的结果类
切面(Aspect、Advisor):由切点和增强(引介)组成(SpringAOP就是负责实施切面的框架,将切面所定义的横切逻辑织入到切面所指定的连接点中)
(注:AOP的工作重心在于如何将增强应用于目标对象的连接点上,包括两个工作:第一,如何通过切点和增强定位到连接点上;第二,如何在增强中编写切面的代码)
2.基础知识
2.1 SpringAOP使用可两种代理机制:一种是基于JDK的动态代理;另一种是基于CGLib的动态代理。之所以需要两种代理机制,很大程度上是因为JDK本身只是提供接口的代理,而不支持类的代理。
2,2 JDK动态代理:主要涉及到java.lang.reflect包中的两个类:Proxy和InvocationHandler(书P181)。
CGLib动态代理:使用JDK创建代理有个限制,即它只能为接口创建代理实例。CGLib对接口与类都可以创建代理实例。
3.Spring通过Advisor(切面)将Pointcut和Advice两者组装起来。有了Advisor的信息,Spring就可以利用JDK或CGLib的动态代理技术采用统一的方式为目标Bean创建织入切面的代理对象了。
CGLib所创建的动态代理对象的性能比JDK所创建的代理对象的性能高(大概10倍),但CGLib在创建代理对象时所花费的时间却比JDK动态代理多(大概8倍)。
所以,对于singleton的代理对象或者具有实例池的代理,无须频繁创建代理对象,适合用CGLib动态代理技术,反之适用JDK动态代理技术。同时,CGLib采用动态创建子类的方式生成代理对象,所以不能对目标类中的final方法进行代理。
4.创建增强类(书P187):
前置增强:BeforeAdvice
后置增强:AfterReturningAdvice
环绕增强:MethodInterceptor
异常抛出增强:ThrowsAdvice
引介增强:IntroductionInteceptor
使用增强,代码直接写是用ProxyFactory类,或者在spring文件中配置,是利用ProxyFactoryBean类(具体配置属性见书P191)
5.创建切面
5.1 前面的增强被织入到目标类的所有方法中,如希望选择特定的方法,需要切点进行目标连接点的定位。
Spring中,Pointcut接口描述切点,Pointcut由ClassFilter和MethodMatcher构成,通过ClassFilter定位到某些特定类上,通过MethodMatcher定位到某些特定方法上。
5.2 切面类型: PointcutAdvisor主要有6个具体实现类:
DefaultPointcutAdvisor:最常用的切面类型,它可通过任意Pointcut和Advice定义一个切面(唯一不支持的是引介的切面类型,一般通过拓展该类实现自定义切面)
NameMatchMethodPointcutAdvisor:通过该类可以定义按方法名定义切点的切面
RegexpMethodPointcutAdvisor:按正则表达式匹配方法名进行切点定义的切面(正则表达式语法见书P207)
StaticMethodMathodMatcherPointcutAdvisor:静态方法匹配器切点定义的切面,默认情况下,匹配所以的目标类。(书P203)
AspectJExpressionPointcutAdvisor:用于AspectJ切点表达式定义切点的切面。
AspectJPointcutAdvisor:用于AspectJ语法定义切点的切面。
5.3 静态切面、动态切面、流程切面、符合切点切面、引介切面...
6.自动创建代理
原理:spring提供自动代理机制,让容器为我们自动生成代理。在内部,通过BeanPostProcessor自动完成。
实现类:
1>基于Bean配置名规则的自动代理创建器:运行为一组特定配置名的Bean自动创建代理实例的代理创建器,实现类为BeanNameAutoProxyCreator;
2>基于Advisor匹配机制的自动代理创建器:它会对容器中所有的Advisor进行扫描,自动将这些切面应用到匹配的Bean中(即为目标Bean创建代理实例),实现类为DefaultAdvisorAutoProxyCreator;
3>基于Bean中AspjectJ注解标签的自动代理创建器:为包含Aspect注解的Bean自动创建代理实例,它的实现类是AnnotationAwareAspectJAutoProxyCreator。