1. 整体
2. 重点
2.1 重要概念
-
切点
-
通知
-
代理
-
拦截
-
增强
2.2 动态代理原理
记住一点,AOP的核心技术就是动态代理
AOP用的是代理,管理代理。java有自带的代理机制,还有Cglb代理机制。这两种机制Aop都在应用,Java代理主要运用于接口,而Cglb主要是类。
很重要的一段话
了解一下ProxyCreatorSupport
AOP的具体实现就是在这个类中。
都是从DefaultAopProxyFactory中的createAopProxy()开始下面操作的。
- 生成代理对象
- 执行拦截器。
JdkDynamicAopProxy拦截器
从JdkDynamicAopProxy的invoke()方法,到ReflectiveMethodInvocation的process()
CglibAopProxy拦截器
intercept()方法,拦截器不是凭空来的,需要进行拦截器注册才能保存到拦截器链中,在拦截器注册之间有一个:从拦截器注册器中进行适配,确定哪些拦截器是该代理目标的拦截器的。
ReflectiveMethodInvocation反射
这里通过反射调用目标方法。 process()方法中实现,这里也是执行matches()的地方。
2.3 invoke()方法逻辑分析
代理中最主要的方法就是invoke()方法了,那就介绍一下该方法的逻辑。
- 获取目标源TargetSource
- 赋值代理目标对象Target
- 获取代理对象类
- 获取代理对象参数,用数组来存放
- 通过反射调用目标方法
- 获取目标方法执行后返回信息
2.4 关于切点
知道切点都是到,就是增强的目标方法,一般是方法。但是Aop怎么知道对那些方法进行操作,这就要在配置的时候告诉Aop需要操作哪些方法。
先看一下Pointcut的整体架构:
这里每一个实现类都要实现一个方法matchs(),至于不同的切点匹配规则不一样。通常用到的
- 方法名
- 注解
- 正则表达式
2.4 Advisor通知器
将增强设计,也就是Advice和切点(Pointcut)结合起来。 也就是哪个切点上使用哪个通知。
2.4.1 DefaultPointcutAdvisor默认切点通知器
也就是当通知器为空的时候,就是用默认的。 默认就是对任何方法的匹配都成功。
TrueMethodMatcher这个方法的匹配对任何方法的匹配都会成功
总结
-
关于Spring AOP的介绍
AOP是基于代理对象的,,通过ProxyCreateSuport来设置创建代理对象的通用操作,在这个类中主要就是获取代理目标对象的SourceTarget,获取代理对象的信息。 -
再通过DefaultAopProxyFactory确定AopProxy代理对象的生成策略,生成策略的配置主要实在createAopProxy()方法中,其实也就是确定是有Java Proxy还是CGLIB第三来生成AopProxy代理对象。
在确定了生成策略之后,真正的Proxy实在ObjenesisCglibAopProxy和JdkDynamicAopProxy类中生成的。 -
代理对象生成之后,在ObjenesisCglibAopProxy-(intercept)和JdkDynamicAopProxy-(invoke)都有自己的回调函数,回调函数的作用就是对代理的方法进行各种增强操作。
-
回调函数的作用是,获取目标对象(包括目标方法,方法参数),拦截器链,创建ReflectiveMethodInvocation的process()方法来完成Aop的各种增强处理。这里的拦截器链其实就是通过遍历连接器链,用一个一个的拦截器来执行拦截增强。
-
这里有一个问题,当拦截器为空的时候,直接使用反射来调用目标方法,不需要创建ReflectiveMethodInvocation。这也是我之前运用AOP的一个例子,没有用到拦截器,获取了代理的目标对象方法之后,通过目标对象方法调用invoke(target, args)来执行方法。
这里记住一点这些操作是在ObjenesisCglibAopProxy-(intercept)和JdkDynamicAopProxy-(invoke)完成的,执行的方法是括号的方法。 -
拦截器分类两种JdkDynamicAopProxy拦截器和CglibAopProxy拦截器,其实不难理解,既然是对AopProxy代理对象的拦截,针对AopProxy两种生成策略,肯定也有两种拦截器。上面已经讲过了,当拦截器链不为空的时候,这两种连接器都是通过ReflectiveMethodInvocation的process()方法进行代理目标函数的增强的。
-
所以接下来的重心就是ReflectiveMethodInvocation的process()方法,该方法中中实现了具体的增强逻辑。贴一个代码吧。代码的核心是从interceptorsAndDynamicMethodMatchers集合中获取拦截器或者拦截通知,然后执行增强操作。这里的interceptorsAndDynamicMethodMatchers连接器接口是从前面提到的方法中传过来的,那就返回获取看看。
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++