spring-beanFactory四
Posted holoyong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring-beanFactory四相关的知识,希望对你有一定的参考价值。
前面简单介绍了beanFactory提供的ioc,我们都知道spring使用jdk的动态代理实现了aop,这篇就来看看spring中的aop到底是怎么回事。
前面有提到,在beanFactory中,getBean会走到AbstractAutowireCapableBeanFactory中的doCreateBean,doCreateBean有如下代码段,populateBean主要是xml注入,initializeBean是初始化,产生aop的逻辑就在initializeBean中。
1 //doCreateBean的主要逻辑 2 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) 3 throws BeanCreationException { 4 //使用工厂方法、构造器注入、简单实例化等策略实例化bean(不是策略模式,只是通过bean definition来决定使用哪种策略,类似switch) 5 //BeanWrapper是bean的包装类,beanWrapper提供了便捷的方法去更新bean的字段、访问bean的方法,用于注入 6 BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);//离我们很近 7 final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); 8 //MergedBeanDefinitionPostProcessor的void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) 9 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 10 // Initialize the bean instance. 11 //exposedObject即暴露的bean、原生的bean 12 Object exposedObject = bean; 13 //先执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation, 14 //再执行InstantiationAwareBeanPostProcessor的postProcessPropertyValues,最后再进行xml注入。 15 //所谓populateBean就是根据该bean在xml的配置信息来填充bean,这些信息已经被解析为BeanDefinition。 16 populateBean(beanName, mbd, instanceWrapper); 17 //什么情况下bean==null? 18 if (exposedObject != null) { 19 //初始化bean 20 //invokeAwareMethods(回调BeanNameAware、BeanClassLoaderAware、BeanFactoryAware的相关方法)、 21 //applyBeanPostProcessorsBeforeInitialization(回调BeanPostProcessor的postProcessBeforeInitialization方法)、 22 //invokeInitMethods(回调InitializingBean的afterPropertiesSet,以及init-method)、 23 //applyBeanPostProcessorsAfterInitialization(回调BeanPostProcessor的postProcessAfterInitialization方法) 24 exposedObject = initializeBean(beanName, exposedObject, mbd);//离我们很近 25 } 26 // Register bean as disposable. 27 registerDisposableBeanIfNecessary(beanName, bean, mbd); 28 }
beanFactory就如同它的名字一样,只适合ID,测试AOP这里使用ClassPathXmlApplicationContext。
Feature | BeanFactory | ApplicationContext |
---|---|---|
Bean instantiation/wiring |
Yes |
Yes |
Automatic |
No |
Yes |
Automatic |
No |
Yes |
Convenient |
No |
Yes |
|
No |
Yes |
1 populateBean(beanName, mbd, instanceWrapper); 2 if (exposedObject != null) { 3 exposedObject = initializeBean(beanName, exposedObject, mbd); 4 }
initializeBean会调用applyBeanPostProcessorsAfterInitialization
1 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) 2 throws BeansException { 3 4 Object result = existingBean; 5 for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { 6 result = beanProcessor.postProcessAfterInitialization(result, beanName); 7 if (result == null) { 8 return result; 9 } 10 } 11 return result; 12 }
我们这里只关注和AOP相关的BeanPostProcessor,即org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator,InfrastructureAdvisorAutoProxyCreator的postProcessAfterInitialization调用的是AbstractAutoProxyCreator的postProcessAfterInitialization,postProcessAfterInitialization又会调用wrapIfNecessary。
1 //有删减 2 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { 3 // Create proxy if we have advice. 4 //得到所有候选Advisor,对Advisors和bean的方法双层遍历匹配,最终得到一个List<Advisor>,即specificInterceptors 5 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); 6 if (specificInterceptors != DO_NOT_PROXY) { 7 this.advisedBeans.put(cacheKey, Boolean.TRUE); 8 //重点方法 9 Object proxy = createProxy( 10 bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); 11 this.proxyTypes.put(cacheKey, proxy.getClass()); 12 return proxy; 13 } 14 }
1 //AbstractAutoProxyCreator的createProxy,有删减 2 protected Object createProxy( 3 Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) { 4 5 ProxyFactory proxyFactory = new ProxyFactory(); 6 //Copy configuration from the other config object. 7 proxyFactory.copyFrom(this); 8 9 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); 10 for (Advisor advisor : advisors) { 11 proxyFactory.addAdvisor(advisor); 12 } 13 //通过targetSource可以得到动态代理的target 14 proxyFactory.setTargetSource(targetSource); 15 //getProxy调用了createAopProxy().getProxy(classLoader),proxyFactory.createAopProxy()创建的是JdkDynamicAopProxy 16 return proxyFactory.getProxy(getProxyClassLoader()); 17 }
1 public Object getProxy(ClassLoader classLoader) { 2 Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true); 3 findDefinedEqualsAndHashCodeMethods(proxiedInterfaces); 4 //jdk的动态代理,因为getProxy的调用者为JdkDynamicAopProxy,所以这里的InvocationHandler就为JdkDynamicAopProxy,最终注册的也是代理bean,target被雪藏 5 return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); 6 }
1 //JdkDynamicAopProxy的invoke方法,有删减 2 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { 3 MethodInvocation invocation; 4 Object oldProxy = null; 5 boolean setProxyContext = false; 6 7 TargetSource targetSource = this.advised.targetSource; 8 Class<?> targetClass = null; 9 Object target = null; 10 11 Object retVal; 12 13 // May be null. Get as late as possible to minimize the time we "own" the target, 14 // in case it comes from a pool. 15 target = targetSource.getTarget(); 16 if (target != null) { 17 targetClass = target.getClass(); 18 } 19 20 // Get the interception chain for this method. 21 //组装拦截链 22 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 23 24 // Check whether we have any advice. If we don\'t, we can fallback on direct 25 // reflective invocation of the target, and avoid creating a MethodInvocation. 26 if (chain.isEmpty()) { 27 // We can skip creating a MethodInvocation: just invoke the target directly 28 // Note that the final invoker must be an InvokerInterceptor so we know it does 29 // nothing but a reflective operation on the target, and no hot swapping or fancy proxying. 30 Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); 31 //通过反射直接调用target的方法 32 retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse); 33 } 34 else { 35 // We need to create a method invocation... 36 invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain); 37 // Proceed to the joinpoint through the interceptor chain. 38 //走拦截链 39 retVal = invocation.proceed(); 40 } 41 //return this时,返回proxy,而不是target 42 // Massage return value if necessary. 43 Class<?> returnType = method.getReturnType(); 44 if (retVal != null && retVal == target && 45 returnType != Object.class && returnType.isInstance(proxy) && 46 !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { 47 // Special case: it returned "this" and the return type of the method 48 // is type-compatible. Note that we can\'t help if the target sets 49 // a reference to itself in another returned object. 50 retVal = proxy; 51 } 52 53 return retVal; 54 55 }
以@Transaction为例来说,XmlBeanFactory在解析xml配置文件时会有专门的NamespaceHandler处理<tx:annotation-driven/>,该NamespaceHandler即TxNamespaceHandler。TxNamespaceHandler会spring注册一个advice,该advice大致会是一个around类型,起到了事务的作用(catch中rollback)。在初始化bean时会遍历bean的方法,检查是否有@Transaction,如果有就对该bean进行动态代理,动态代理中会存该bean的method到adviceChain的映射,执行@Transactional方法时就会从该映射中得到adviceChain。
以上是关于spring-beanFactory四的主要内容,如果未能解决你的问题,请参考以下文章