Spring AOP的实现可以分为三大部分
1. 注册AOP功能具体实现类
2. 普通Bean实例化时AOP的切入
3. AOP切入具体流程
下面分析BeanPostProcessor执行过程中,aop如何切入,上一节讲到,普通bean初始化会调用如下方法
// 调用AOP的真正实现方法入口
result = beanProcessor.postProcessAfterInitialization(result, beanName);
aop此方法实际是继承自AbstractAutoProxyCreator, 跟踪一下
postProcessAfterInitialization的实现
创建代理实际只有两个步骤
1. 获取增强方法或者增强器
2. 根据获取到的增强器进行代理
// class
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
// 进行aop包装
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 1. 获取增强器, 下面会详细拆分
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
// 如果获取到aop拦截器
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 2. 创建代理
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
// 最终返回aop代理类
return proxy;
}
首先跟踪 获取增强器 的逻辑
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
// 封装在函数内
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 获取增强器,其内部实现具体为以下步骤
// 1. 获取beanFactory所有的beanName
// 2. 遍历所有beanName,找到声明为AspectJ的类
// 3. 对第二步的类,进行增强器提取
// 4. 将提取结果加入缓存(提升下次调用的的效率,因为每个bean都会走这个流程)
// 增强器实际会根据method上的注解(Before, After...)初始化不同的类,比如 Before 注解对应 AspectJMethodBeforeAdvice
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 判断当前bean可用的增强器,因为不一定所有的增强器对当前bean适用
List<Advisor> eligibleAdvisors =
findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
继续跟踪 创建代理 实现
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
......
// 统一处理封装所有的的增强器
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
......
// 生成代理,并返回,生成代理会有两种方式
// 对于实现了接口的类,默认使用jdk动态代理; 对于没有实现接口的类,只能使用cglib
// 对于实现了接口的类,可以强制使用cglib(通过配置proxy-target-class="true")
return proxyFactory.getProxy(getProxyClassLoader());
}
代理的真正实现调用过程(jdk动态代理,或者cglib)不再赘述,比如动态代理,最终会调用invoke,稍微看一下JdkDynamicAopProxy的invoke实现,内部通过chain保存了增强器调用链,实现过程类似于职责链设计模式
// class JdkDynamicAopProxy
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
......
// 获取并封装调用链chain,实际会对advisor进行转换,比如 (@Before注解)AspectJMethodBeforeAdvice
会转换为 MethodBeforeAdviceInterceptor
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);
// 实际执行比较有意思,会loop chain,但是需要仔细看逻辑才明白
retVal = invocation.proceed();
}
......
}
public Object proceed() throws Throwable {
// interceptorsAndDynamicMethodMatchers实际是上面的调用链chain,若到达队尾,则跳出
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 获取下一个interceptor
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
......
// 这个方法,将this传了进去,里面的实现可以看出,实际在执行完当前interceptor的invoke方法后,接着执行this.proceed,即又调用回来了当前proceed方法,保证loop chain完成
return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this);
}
// 比如 MethodBeforeAdviceInterceptor 的实现
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
// advice封装了advisor
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
// mi即为上面的invoke方法传入的this
return mi.proceed();
}