真是不想再读spring了 很花时间,我可是急性子
总结一下看aop的收获:
首先,spring中有一些个术语,自己记不清楚。抽象一点就好理解了。advice,就理解成普通类就性了。pointcut实际上可以看成一个用来判断哪里需要代理的类,它应该包含一个正则表达式或者map什么的用来判断。advisor可以看成拥有pointcut和advice的一个类,它先用pointcut判断再调用advice。proxyBean则可以看成一个包含了被代理类target和一个通知器链条的类,它先挨个调用链条上的advisor最后调用target的方法。在spring配置文件里形象的表示为:
转自http://blog.csdn.net/turkeyzhou/article/details/3009495
<bean name="advice" id="advice" class="org.syna.demo.BeforeAdvice"></bean> <bean name="pointcut" id="pointcut" class="org.springframework.aop.support.NameMatchMethodPointcut"> <property name="mappedName"> <value>*say</value> </property> </bean> <bean id="advisor" name="advisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="advice"> <ref local="advice" /> </property> <property name="pointcut"> <ref local="pointcut" /> </property> </bean> <bean name="proxyBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <ref local="person" /> </property> <property name="interceptorNames"> <list> <idref local="advisor" /> </list> </property> </bean>
然后进入正题,代理类是从哪里来的:
在createBean方法中有一句Object bean = resolveBeforeInstantiation(beanName, mbd);
进入到这个方法:
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { 02 Object bean = null; 03 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { 04 // Make sure bean class is actually resolved at this point. 05 if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { 06 bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName); 07 if (bean != null) { 08 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); 09 } 10 } 11 mbd.beforeInstantiationResolved = (bean != null); 12 } 13 return bean; 14 }
在方法
bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
里,如果bean需要创建代理就会创建代理,不需要的话返回null,回到住方法后,如果为null就去doCreateBean(),不是null就不会继续往下执行了。
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { Object cacheKey = getCacheKey(beanClass, beanName); if (!this.targetSourcedBeans.contains(cacheKey)) { if (this.advisedBeans.contains(cacheKey) || this.nonAdvisedBeans.contains(cacheKey)) { return null; } if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) { this.nonAdvisedBeans.add(cacheKey); return null; } } // Create proxy here if we have a custom TargetSource. // Suppresses unnecessary default instantiation of the target bean: // The TargetSource will handle target instances in a custom fashion. TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { this.targetSourcedBeans.add(beanName); Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } return null; }
这个方法中 获得了可能跟bean有关的advisors
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass
然后调用了createProxy();
protected Object createProxy( Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) { ProxyFactory proxyFactory = new ProxyFactory(); // Copy our properties (proxyTargetClass etc) inherited from ProxyConfig. proxyFactory.copyFrom(this); if (!shouldProxyTargetClass(beanClass, beanName)) { // Must allow for introductions; can't just set interfaces to // the target's interfaces only. Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, this.proxyClassLoader); for (Class<?> targetInterface : targetInterfaces) { proxyFactory.addInterface(targetInterface); } } Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); for (Advisor advisor : advisors) { proxyFactory.addAdvisor(advisor); } proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(this.proxyClassLoader); }
这个方法返回的到底是什么,真的很搞人,搞的我再也不想看spring源码了。先要看ProxyFactory这个类到底是干嘛的。翻看源码ProxyFactory只是写了一些构造方法和一些getProxy()方法,但身世比较复杂。ProxyFactory继承自ProxyCreateSupport,听名字这个类主要是用来创建proxy的,他实现了protected final synchronized AopProxy createAopProxy()这个方法,而这个方法是通过持有一个DefaultAopProxyFactory对象来实现的,真正的createAopProxy()方法也是在DefaultAopProxyFactory中实现的,看看DefaultAopProxyFactory的这个方法:
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { 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."); } if (targetClass.isInterface()) { return new JdkDynamicAopProxy(config); } return CglibProxyFactory.createCglibProxy(config); } else { return new JdkDynamicAopProxy(config); } }
这个DefaultAopProxyFactory的createProxy方法返回的是我们学aop原理时候看到的JdkDynamicAopProxy和Cglib,比如JdkDynamicAopProxy这个类实现了InvocationHandler接口,到这里就好懂了。另外要说的是ProxyCreateSupport继承了AdvisedSupport,而AdvisedSupport里面有各种资源,有target,interfaces,advisors等等,这个类又继承了ProxyCofig.
弄清楚各个类和主要的方法后在回去分析createProxy方法到底返回了什么。首先new了一个ProxyFactory然后调用了他的getProxy(this.proxyClassLoader);然后ProxyFactory自己去调用:
public Object getProxy(ClassLoader classLoader) { return createAopProxy().getProxy(classLoader); }
createAopProxy()在ProxyCreateSupport中,他调用了defaultAopProxyFactory的createProxy的方法,所以返回的是JdkDynamicAopProxy,也就是实现了InvocationHandler的类。
所以最终返回的是Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); 也就是代理类。