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 }
View Code

 

beanFactory就如同它的名字一样,只适合ID,测试AOP这里使用ClassPathXmlApplicationContext。

FeatureBeanFactoryApplicationContext

Bean instantiation/wiring

Yes

Yes

Automatic BeanPostProcessor registration

No

Yes

Automatic BeanFactoryPostProcessor registration

No

Yes

Convenient MessageSource access (for i18n)

No

Yes

ApplicationEvent publication

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四的主要内容,如果未能解决你的问题,请参考以下文章

验证码逆向专栏某验四代文字点选验证码逆向分析

验证码逆向专栏某验四代消消乐验证码逆向分析

spring-beanFactory二

spring-beanFactory三

Spring-BeanFactory容器

spring-beanFactory四