- spring在创建完bean原始实例后,需要判断是否需要给当前bean创建代理对象。
- initializeBean时会调用applyBeanPostProcessorsAfterInitialization方法,该方法会调用所有BeanPostProcessor的postProcessAfterInitialization。
- AbstractAutoProxyCreator就是一个BeanPostProcessor,该类的postProcessAfterInitialization会调用wrapIfNecessary方法,即该bean是否需要被包装成代理对象。是否需要代理原则就是该bean有没有与之相关的Advisor,有就代理。
// 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;
}
getAdvicesAndAdvisorsForBean会调用AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
protected ListfindEligibleAdvisors(Class> beanClass, String beanName) { //查找所有的Advisor List candidateAdvisors = findCandidateAdvisors(); //查找所有的Advisor中可应用的某个bean的Advisor List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
findCandidateAdvisors()源码简单可总结为:从容器中获取所有实现了Advisor的类,在加上aspectJ创建的Advisor。
接下来我们看下findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName)源码
protected ListfindAdvisorsThatCanApply( List candidateAdvisors, Class> beanClass, String beanName) { //在ThreadLocal中标记当前beanName ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { //在ThreadLocal中移除当前beanName ProxyCreationContext.setCurrentProxiedBeanName(null); } }
AopUtils findAdvisorsThatCanApply源码分析
public static ListfindAdvisorsThatCanApply(List candidateAdvisors, Class> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List eligibleAdvisors = new ArrayList<>(); for (Advisor candidate : candidateAdvisors) { //是否为引入切面并且是否能被应用到 if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } //目前用不到IntroductionAdvisor ,所以值为false,看常用的就行 boolean hasIntroductions = !eligibleAdvisors.isEmpty(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor) { // already processed continue; } if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; }
接着看canApply方法
public static boolean canApply(Advisor advisor, Class> targetClass, boolean hasIntroductions) {
//这里也不关注引入Advisor
if (advisor instanceof IntroductionAdvisor) {
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
//只要看PointcutAdvisor就行
else if (advisor instanceof PointcutAdvisor) {
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
接着看canApply方法
public static boolean canApply(Pointcut pc, Class> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
//1
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
//2
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
//3
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
//4
Set> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
//5
for (Class> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {
return true;
}
}
}
return false;
}
- 先用PointcutAdvisor过滤,true继续
- 判断methodMatcher 是否为TrueMethodMatcher,因为TrueMethodMatcher永远匹配都是true。不是的话继续
- 如果是引入类型的methodMatcher则强转,这里也不讨论
- 查找当前类及其祖宗类实现的所有接口
- 遍历这些class。获取每个class方法列表包含从父类继承的的方法。接着调用2个参数的methodMatcher#matches方法,如果为true则返回,false则接着循环。



