码迷,mamicode.com
首页 > 编程语言 > 详细

spring-beanFactory四

时间:2017-08-18 17:14:14      阅读:247      评论:0      收藏:0      [点我收藏+]

标签:oss   center   fan   lsa   ref   specific   注入   struct   text   

前面简单介绍了beanFactory提供的ioc,我们都知道spring使用jdk的动态代理实现了aop,这篇就来看看spring中的aop到底是怎么回事。

 

前面有提到,在beanFactory中,getBean会走到AbstractAutowireCapableBeanFactory中的doCreateBean,doCreateBean有如下代码段,populateBean主要是xml注入,initializeBean是初始化,产生aop的逻辑就在initializeBean中。

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 }

 

spring-beanFactory四

标签:oss   center   fan   lsa   ref   specific   注入   struct   text   

原文地址:http://www.cnblogs.com/holoyong/p/7367741.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!