public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
关键便在于wrapIfNecessary方法: 名字 wrap if Necessary 如果满足条件就包装这个方法就可以拆成两部分看:
- 满足条件:
- 包装:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //1.自定义TargetSource,已经进行过代理子类生成 。 不包装直接返回Bean实例 if (beanName != null && this.targetSourcedBeans.contains(beanName)) { return bean; } //2.已经判定不需要代理的, 不代理 if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } //3.isInfrastructureClass(bean.getClass())是基础设施类的不代理 //4.shouldSkip(bean.getClass(), beanName)应该跳过的不代理 if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. 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; } //5.没有具体拦截器的不代理 this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
我们挨个分析下这两部分
(2.4.1) 满足条件
不代理的情况:
- 自定义TargetSource,已经进行过代理子类生成 。 不包装直接返回Bean实例。()
- 已经判定不需要代理的, 不代理。 直接返回Bean实例
- isInfrastructureClass(bean.getClass())是基础设施类的不代理。 (上文已经提过)
- shouldSkip(bean.getClass(), beanName)应该跳过的不代理 (上文已经提过)
- 没有具体拦截器的不代理
代理的的情况:
- 有具体Advice的才代理:getAdvicesAndAdvisorsForBean() 的返回不为空的。(Create proxy if we have advice.)
Advisor寻找:重点就落在了此处。
即getAdvicesAndAdvisorsForBean方法,这里进行的便是去容器中寻找适用于当前bean的Advisor,最终调用的是
AbstractAdvisorAutoProxyCreator.findEligibleAdvisors:
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { List<Advisor> candidateAdvisors = findCandidateAdvisors(); List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
- findCandidateAdvisors: 获取所有Advisor ,前面已经说过。 因为做了缓存此处直接从缓存中取。
- findAdvisorsThatCanApply: 看其传入的参数,candidateAdvisors(所有的候选Advisor), 也就是这个方法肯定就是从所有的候选Advisor找出适合当前Bean
- extendAdvisors: 允许子类添加advisor
适用性判断findAdvisorsThatCanApply最终调用AopUtils.findAdvisorsThatCanApply:
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> eligibleAdvisors = new LinkedList<Advisor>(); //第一遍 for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } //第一遍 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; }
此方法有两个for循环。 第一个for循环寻找IntroductionAdvisor(引介增强)类型的advisor,调用AopUtils.canApply 第二遍for循环寻找普通的advisor,调用AopUtils.canApply
AopUtils.canApply针对两种类型的Advisor做了不同的判断:
- 针对IntroductionAdvisor类型advisor的,只需要校验Advisor的ClassFilter是否匹配当前类
- 针对普通的advisor:(1)首先查看定的类是否在Pointcut的匹配范围内;(2)是的话,再查看是否能匹配此类任意方法,是的话返回true;(3)不能匹配任意方法,便会用反射的方法获取targetClass(被检测类)的全部方法逐一交由Pointcut的MethodMatcher.matches方法进行检测。
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { Assert.notNull(pc, "Pointcut must not be null"); if (!pc.getClassFilter().matches(targetClass)) { return false; } //是否配置任意方法 MethodMatcher methodMatcher = pc.getMethodMatcher(); if (methodMatcher == MethodMatcher.TRUE) { // No need to iterate the methods if we're matching any method anyway... return true; } IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; } //逐一排查 Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); classes.add(targetClass); 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; }
到此,AopUtils.canApply返回true后。findAdvisorsThatCanApply()算是找到了能应用于当前类的Advisors. 再extendAdvisors后;对,应用于当前类的Advisors一番排序后,getAdvicesAndAdvisorsForBean工作完成。
getAdvicesAndAdvisorsForBean()返回如果不为Null。那下面就是包装。
(2.4.2) 包装在getAdvicesAndAdvisorsForBean返回advisors不为null后,可以创建代理。
protected Object createProxy( Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) { ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(getProxyClassLoader()); }
- 首先创建ProxyFactory 工厂,从AbstractAutoProxyCreator复制代理属性,因为AbstractAutoProxyCreator继承了ProxyConfig,所以本身也是一个代理配置类。
- 判断其是基于类代理, 还是基于接口代理。如果基于接口代理,获取接口,并设置到ProxyFactory 。
- buildAdvisors()方法,整合getAdvicesAndAdvisorsForBean找的advisors 与AbstractAutoProxyCreator. interceptorNames属性可能设置的增强器,统一包装成Advisor类型数组,设置到ProxyFactory 。并且AbstractAutoProxyCreator. interceptorNames属性设置的增强器在前。
- customizeProxyFactory(proxyFactory); 子类可以继续处理ProxyFactory
- 设置ProxyFactory的Frozen属性
- setPreFiltered设置ProxyFactory 的preFiltered
- getProxy 返回代理对象
我们可以看出,这里两大部分:
(1)创建proxyFactory工厂,并配置工厂
(2)proxyFactory.getProxy(getProxyClassLoader())返回代理对象。
proxyFactory.getProxy(ClassLoader classLoader)
proxyFactory.getProxy(ClassLoader classLoader) 首先会先创建一个默认的策略工厂DefaultAopProxyFactory。DefaultAopProxyFactory 会根据proxyFactory是基于接口的代理还是基于类的代理,选择创建JdkDynamicAopProxy对象,或者创建一个CglibAopProxy对象
这里有必要介绍下DefaultAopProxyFactory.createAopProxy方法,此方法用来判断是JDK代理,还是CGLB代理。
if (config.isOptimize() //是否对代理类的生成使用策略优化 || config.isProxyTargetClass() //设置proxy-target-class="true || hasNoUserSuppliedProxyInterfaces(config)) {//目标类是否有接口存在 且只有一个接口的时候接口类型不是 //SpringProxy类型 Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } //判断目标类是否是接口 如果目标类是接口的话,则还是使用JDK的方式生成代理对象 //如果目标类是Proxy类型 则还是使用JDK的方式生成代理对象 if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } //CGLB代理。 return new ObjenesisCglibAopProxy(config); } else { //JDK代理 return new JdkDynamicAopProxy(config); }
我们可以看出高版本的会根据设置和目标类的实际情况选择使用CGLB或者JDK代理。也就是说,设置了
proxy-target-class="true"
不一定就是使用CGLB,而是根据实际情况定。具体版本具体对待。
JdkDynamicAopProxy.getProxy()或者CglibAopProxygetProxy()才是真正返回代理对象。
JdkDynamicAopProxy.getProxy()
@Override public Object getProxy(ClassLoader classLoader) { if (logger.isDebugEnabled()) { logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource()); } Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); }
我们看到JDK动态代理的两个要素: Proxy+InvocationHandlerInvocationHandler 此时就是JdkDynamicAopProxy,同时JdkDynamicAopProxy封装了advised。这样完美的把advised与JDK动态代理联系在了一起。
接下来就是在内存中生成一个字节码JDK代理类$Proxy66.class,生成真正的代理对象了。
CglibAopProxygetProxy()(省略部分源码,直奔主题)
// Configure CGLIB Enhancer... Enhancer enhancer = createEnhancer(); Callback[] callbacks = getCallbacks(rootClass); enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised)); return createProxyClassAndInstance(enhancer, callbacks); }
我们看到了Cglb熟悉的要素Enhancer 。MethodInterceptor去哪了呢?
跟进getCallbacks()方法,会发现此方法会创建一个DynamicAdvisedInterceptor。DynamicAdvisedInterceptor实现了MethodInterceptor,并封装了advisors。
Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
这样,CGLB动态代理完美的与advised结合在了一起。 接下来就是在内存中生成一个新的字节码CGLB代理类***?FastClassByCGLIB?29e52466
,并生成真实代理对象了。
总结
springaop 底层还是JDK动态代理,CGLB动态代理。通过把增强器封装到Advised中,把Advised与InvocationHandler或者MethodInterceptor联系起来,完美的实现AOP技术。