上一篇文章https://blog.csdn.net/sinat_33472737/article/details/105414097我们了解到了spring是如何把Advisor关联起来的,
wrapIfNecessary部分源码
// Create proxy if we have advice.
//获取bean有关的Advisor
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
当和某个bean有关联的Advisor时,spring就会为该bean创建代理对象,并将这些相关的Advisor存储到代理对象中。
我们以JdkDynamicAopProxy为例分析spring具体是怎么判断某个方法需要执行哪些Advisor中的Advice。JdkDynamicAopProxy中invoke中下方代码就是获取和方法相关的Advisor中的Advice,在spring中就是MethodInterceptor
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
该方法最终会调用org.springframework.aop.framework.DefaultAdvisorChainFactory的getInterceptorsAndDynamicInterceptionAdvice方法
public List<Object> getInterceptorsAndDynamicInterceptionAdvice( Advised config, Method method, @Nullable Class<?> targetClass) { // This is somewhat tricky... We have to process introductions first, // but we need to preserve order in the ultimate list. AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); Advisor[] advisors = config.getAdvisors(); List<Object> interceptorList = new ArrayList<>(advisors.length); Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass()); Boolean hasIntroductions = null; for (Advisor advisor : advisors) { if (advisor instanceof PointcutAdvisor) { // Add it conditionally. PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); boolean match; if (mm instanceof IntroductionAwareMethodMatcher) { if (hasIntroductions == null) { hasIntroductions = hasMatchingIntroductions(advisors, actualClass); } match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions); } else { match = mm.matches(method, actualClass); } if (match) { MethodInterceptor[] interceptors = registry.getInterceptors(advisor); if (mm.isRuntime()) { // Creating a new object instance in the getInterceptors() method // isn't a problem as we normally cache created chains. for (MethodInterceptor interceptor : interceptors) { interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm)); } } else { interceptorList.addAll(Arrays.asList(interceptors)); } } } } else if (advisor instanceof IntroductionAdvisor) { IntroductionAdvisor ia = (IntroductionAdvisor) advisor; if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } else { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } return interceptorList; }
原理也是通过pointcut的ClassFilter和MethodMatcher 进行匹配,匹配结果为true的话,调用org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry的getInterceptors方法,包装成MethodInterceptor返回