SpringAOP终结篇(补充中...)
Posted 一点学习的记录
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringAOP终结篇(补充中...)相关的知识,希望对你有一定的参考价值。
一、基本源码分析
1.寻找入口
Spring 的 AOP 是通过接入 BeanPostProcessor 后置处理器开始的
2.BeanPostProcessor
BeanPostProcessor的体现在IOC源码分析的doCreateBean中,populateBean的后一句
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
initializeBean中,在调用invokeInitMethods初始化方法的前后调用BeanPostProcessor
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
//...
}
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
其实就是在你的init方法前后调用BeanPostProcessor的before方法和after方法。
在 Spring 中,BeanPostProcessor 的实现子类非常的多,分别完成不同的操作,如:AOP 面向切面编程的注册通知适配器、Bean 对象的数据校验、Bean 继承属性、方法的合并等等。
分析创建AOP代理对象的相关BeanPostProcessor子类AbstractAutoProxyCreator(经典实现类AnnotationAwareAspectJAutoProxyCreator) 。
3.AbstractAutoProxyCreator
AbstractAutoProxyCreator的postProcessAfterInitialization ,即after方法
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
核心逻辑在wrapIfNecessary,里面主要几步
1.判断是不是该wrap包装(AOP代理):是不是缓存过、基础Bean(Advice/PointCut/Advisor)跳过
2.获取这个Bean的advice
3.处理advice去createProxy创建代理对象并缓存
核心当然是createProxy,最终是交给了工厂proxyFactory.getProxy(),最终到DefaultAopProxyFactory的 createAopProxy()方法
4.DefaultAopProxyFactory#createAopProxy()
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
//...
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
两种方式来生成代理方式有 JDKProxy 和 CGLib
来分析一下spring中JDK动态代理如何运作的,织入切面的,对应是JdkDynamicAopProxy
5.JdkDynamicAopProxy
InvocationHandler 是 JDK 动态代理的核心,生成的代理对象的方法调用都会委托到InvocationHandler.invoke()方法。JdkDynamicAopProxy 的源码可以看到这个类也实现了 InvocationHandler,
5.1 invoke()方法:
避免一些不aop的特殊情况后,首先获取应用到此方法上的通知链(Interceptor Chain)。如果有通知,则应用通知,并执行 JoinPoint;如果没有通知,则直接反射执行 JoinPoint。
5.2 获取通知链
getInterceptorsAndDynamicInterceptionAdvice 方法:
1从提供的配置实例 config 中获取 advisor 列表,
2 遍历处理这些 advisor.如果是 IntroductionAdvisor,则判断此 Advisor 能否应用到目标类 targetClass 上.
3.如果是 PointcutAdvisor,则判断此 Advisor 能否应用到目标方法 Method 上.
4.将满足条件的 Advisor 通过 AdvisorAdaptor 转化成 Interceptor 列表返回.
这个方法执行完成后,Advised 中配置能够应用到连接点(JoinPoint)或者目标类(Target Object)
的 Advisor 全部被转化成了 MethodInterceptor
5.3 执行
获取完通知链之后就是执行了:
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();
}
核心就是retVal = invocation.proceed();打开ReflectiveMethodInvocation的proceed源码:
public Object proceed() throws Throwable {
//1.如果 Interceptor 执行完了, 则执行 joinPoint
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
//2.如果要动态匹配 joinPoint
InterceptorAndDynamicMethodMatcher dm =(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
//3.动态匹配: 运行时参数是否满足匹配条件
if (dm.MethodMatcher.matches(this.Method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
} else {
//动态匹配失败时,略过当前 Intercetpor,调用下一个 Interceptor
return proceed();
}
} else {
//4.执行当前 Intercetpor
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
1.从执行链里取Interceptor(排序好了,依次是before、after、return、afterthrowing)
2.分两种情况,Interceptor是否是动态匹配型的
? 2.1 动态匹配型,去执行动态匹配代码,匹配上则执行
? 2.2 普通型else,直接执行Interceptor逻辑(这个逻辑里排好代码,是先继续递归还是先执行自己,before是先执行自己)如下:
beofore-Interceptor的的invoke(先自己再继续递归)
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
after-Interceptor的的invoke(先继续递归,再执行自己)
public Object invoke(MethodInvocation mi) throws Throwable {
try {
return mi.proceed();
}
finally {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
以上是关于SpringAOP终结篇(补充中...)的主要内容,如果未能解决你的问题,请参考以下文章