创建
AbstractAutoProxyCreator->wrapIfNecessary():
// 如果有的话,就创建代理
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
先遍历切面方法,如果未解析会先解析切面表达式,之后查看bean的类和方法,看是否符合切面表达式,符合的话,返回的specificInterceptors就不会为空了
AopUtils->canApply():
// 这里matches方法一般都返回true,但是getClassFilter第一次调用时,会解析切面方法
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
......
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
// 不同的切面表达式有不同的逻辑,但最终都是遍历方法,返回true或false
// 比如@annotation()是看方法有无目标注解
// @within()是看类有无目标注解
// 由此可见,只要有一个方法满足了切面表达式,就会创建aop代理
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
AbstractAutoProxyCreator->wrapIfNecessary():
// 根据返回的specificInterceptors是否为空来判断是否满足切面表达式
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
// 这里返回的的proxy即为被代理的对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
// 不满足切面表达式的情况
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
AbstractAutoProxyCreator->createProxy():
return proxyFactory.getProxy(getProxyClassLoader());
ProxyFactory->getProxy():
return createAopProxy().getProxy(classLoader);
ProxyCreatorSupport->createAopProxy():
return getAopProxyFactory().createAopProxy(this);
DefaultAopProxyFactory->createAopProxy():
// 如果目标类是接口或者是Proxy类及其子类的话,创建jdk动态代理,否则创建cglib代理
// 通俗来说,就是,jdk动态代理只能创建接口的动态代理,而cglib可以创建普通类的动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
下图是普通bean与cglib增强bean的构造区别:
AoP部分与
CglibAopProxy$DynamicAdvisedInterceptor有关,advisors以及advisorArray是满足切面表达式的Advisor实现类。
运行
AoP代理的主要逻辑是遍历advisorArray,获得方法满足的切面方法,然后调用advisor.getAdvice()获得Advice实现类,放入拦截器集合中,之后以类似责任链模式执行,详细代码见CglibAopProxy->DynamicAdvisedInterceptor->intercept()、DefaultAdvisorChainFactory->getInterceptorsAndDynamicInterceptionAdvice()、ReflectiveMethodInvocation->proceed()。
这里需要获得方法满足的切面方法,是因为有的AoP只对满足表达式的方法生效,其他方法不生效,但是方法寄生于类上,所以该类会是一个增强类,当然,对类生效的一定对方法生效。
小结:
- aop的实现载体是动态代理,实例化完成之后,利用了IoC的后置处理器
AnnotationAwareAspectJAutoProxyCreator,通过它的postProcessAfterInitialization()方法来判断bean实例是否需要被代理,若满足表达式,则返回代理bean,否则,返回原始bean实例 @Around/@Before/@After/@AfterReturning/@AfterThrowing这些注解决定的是方法的执行顺序- 一般方法的执行顺序为:doAround()->proceedingJoinPoint.proceed()->doBefore()->add()->doAfterReturning()->doAfter()->doAround()
- 报异常时的执行顺序为:doAround()->proceedingJoinPoint.proceed()->doBefore()->add()->doAfterThrowing()->doAfter()
- 对于Advisor类,看是否满足切面表达式的过程
- 调用
advisor.getPointcut() - 调用
pointCut.getMethodMatcher() - 根据methodMatcher的实现类调用不同的匹配方法,返回true则是满足
- 如果methodMatcher是
IntroductionAwareMethodMatcher实现类,那么调用introductionAwareMethodMatcher.matches(Method method, Class<?> targetClass, boolean hasIntroductions) - 否则调用
methodMatcher.matches(Method method, Class<?> targetClass)
- 如果methodMatcher是
- 调用
- 根据增强类反推Advisor以及拦截器
- 如果一个增强类有成员变量
CglibAopProxy$DynamicAdvisedInterceptor说明它有AoP代理 - 它有唯一的成员变量advised,advisor位于其advisors成员变量中,这是一个List集合
- advice是切面拦截器,运行时会执行它的
invoke()方法;pointcut是切面类,可以根据它查看切面表达式;order是排序,越小越先执行
- 如果一个增强类有成员变量