从BeanDefinition到Bean

    当 BeanDefinition 注册完毕以后, Spring Bean 工厂就可以随时根据需要进行实例化了。对于 XmlBeanFactory 来说,实例化默认是延迟进行的,也就是说在 getBean 的时候才会;而对于 ApplicationContext 来说,实例化会在容器启动后通过 AbstractApplicationContext 中 reflash 方法自动进行,主要经过方法链: reflesh()   à finishBeanFactoryInitialization (factory) à DefaultListableBeanFactory.preInstantiateSingletons (), 在这里会根据注册的 BeanDefinition 信息依此调用 getBean(beanName) 。而真正实例化的逻辑和 BeanFactory 是“殊途同归”的,所有有关 Bean 实例化都可以从 getBean(beanName) 入手。

      AbstractBeanFactory 有四个 getBean 的重载方法,不管调用哪个方法最终都是会调用另一个 doGetBean 方法:

public Object getBean(String name) throws BeansException {
		return getBean(name, null, null);
	}
		
	public Object getBean(String name, Class requiredType) throws BeansException {
		return getBean(name, requiredType, null);
	}

	public Object getBean(String name, Object[] args) throws BeansException {
		return getBean(name, null, args);
	}

	/**
	 * Return an instance, which may be shared or independent, of the specified bean.
	 * @param name the name of the bean to retrieve
	 * @param requiredType the required type of the bean to retrieve
	 * @param args arguments to use if creating a prototype using explicit arguments to a
	 * static factory method. It is invalid to use a non-null args value in any other case.
	 * @return an instance of the bean
	 * @throws BeansException if the bean could not be created
	 */
	public Object getBean(String name, Class requiredType, Object[] args) throws BeansException {
		return doGetBean(name, requiredType, args, false);
	}

        doGetBean方法比较长一点,见下面注释:

protected Object doGetBean(
final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly) 
throws BeansException {
//bean name处理,去除FactoryBean前缀等
     final String beanName = transformedBeanName(name);
     Object bean = null;

//先从singleton缓存中查看是否已经实例化过该Bean,根据是否有缓存分为两个分支分别处理
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
// 分支一,若缓存中获取到了并且该BeanDefinition信息表明该bean是singleton的,直接将获取到的缓存Bean
//(有可能是半成品)交给getObjectForBeanInstance处理
 /*.........省略logger部分代码............*/
//调用getObjectForBeanInstance处理
     bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }else {
// 分之二:没有缓存,则需要从头实例化该bean
			// We're assumably within a circular reference.
      if (isPrototypeCurrentlyInCreation(beanName)) { 
           throw new BeanCurrentlyInCreationException(beanName);}

// 检查BeanDefinition是否在当前工厂或父工厂
			BeanFactory parentBeanFactory = getParentBeanFactory();
			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
				String nameToLookup = originalBeanName(name);
				if (args != null) {
// 父工厂getBean
					return parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
					// No args -> delegate to standard getBean method.
					return parentBeanFactory.getBean(nameToLookup, requiredType);
				}
			}
//将bean加入“正在创建”的集合,完成后会remove,对应afterSingletonCreation/afterPrototypeCreation方法
			if (!typeCheckOnly) {
				markBeanAsCreated(beanName);
			}

			final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			checkMergedBeanDefinition(mbd, beanName, args);

// 解决依赖关系,将依赖的bean提前实例化
			String[] dependsOn = mbd.getDependsOn();
			if (dependsOn != null) {
				for (int i = 0; i < dependsOn.length; i++) {
					String dependsOnBean = dependsOn[i];
					getBean(dependsOnBean);
					registerDependentBean(dependsOnBean, beanName);
				}
			}

// 这里又需要根据bean的类型分为三种情况:singleton、prototype、request/session
			if (mbd.isSingleton()) {
                           //通过自定义ObjectFactory实例化Bean,此结果可能是半成品(是FactoryBean等)
				sharedInstance = getSingleton(beanName, new ObjectFactory() {
					public Object getObject() throws BeansException {
						try {
                          //真正实例化装配的逻辑在createBean方法中
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
			// Explicitly remove instance from singleton cache: It might have been put there
			// eagerly by the creation process, to allow for circular reference resolution.
			// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					}
				});
                        //上一步半成品的Bean交给getObjectForBeanInstance方法处理
				bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}

			else if (mbd.isPrototype()) {
				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
                     //真正实例化装配的逻辑在createBean方法中
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
                    //上一步半成品的Bean交给getObjectForBeanInstance方法处理
			   bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}

			else {
                            //request、session 的bean
				String scopeName = mbd.getScope();
				final Scope scope = (Scope) this.scopes.get(scopeName);
				if (scope == null) {
		throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, new ObjectFactory() {
						public Object getObject() throws BeansException {
							beforePrototypeCreation(beanName);
							try {
                         //真正实例化装配的逻辑在createBean方法中
								return createBean(beanName, mbd, args);
							}
							finally {
								afterPrototypeCreation(beanName);
							}
						}
					});
                       //上一步半成品的Bean交给getObjectForBeanInstance方法处理
				bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				}
				catch (IllegalStateException ex) {
					throw new BeanCreationException(beanName,
				"Scope '" + scopeName + "' is not active for the current thread; " +
	"consider defining a scoped proxy for this bean if you intend to refer to it from a singleton",
							ex);
				}
			}
		}

		// Check if required type matches the type of the actual bean instance.
		if (requiredType != null && bean != null &&
                              !requiredType.isAssignableFrom(bean.getClass())) {
			throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
		}
		return bean;
	}

 

      通过注释,可以整理出较清晰的逻辑: 检查Bean缓存,已经有缓存的Bean对象(有可能是半成品)则交给getObjectForBeanInstance方法处理;否则先根据Bean的生命周期类型分别实例化,每种情况大致都分两步,第一步都交给createBean方法生产一个半成品的bean对象,然后同样是将半成品的bean交给getObjectForBeanInstance方法处理。所以关键的逻辑就在这两个方法了,下面以singleton为例看看这两个方法,具体代码:

 

sharedInstance = getSingleton(beanName, new ObjectFactory() {
					public Object getObject() throws BeansException {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							// Explicitly remove instance from singleton cache: It might have been put there
							// eagerly by the creation process, to allow for circular reference resolution.
							// Also remove any beans that received a temporary reference to the bean.
							destroySingleton(beanName);
							throw ex;
						}
					}
				});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);

       getSingleton方法做的工作主要是实例化bean之前和之后回调beforeSingletonCreation/afterSingletonCreation、实例化bean、以及将bean对象缓存起来,具体实例化bean是通过回调匿名对象ObjectFactory的getObject方法实现的,从代码中明显看到主要是createBean方法。这里要特别注意下,缓存的bean对象是createBean生产的,这个方法生产的bean只是“半成品”,有可能是个factoryBean,真正返回给客户端使用的bean还必须进行下一步getObjectBeanInstance处理。所以缓存的bean对象可以认为是“半成品”,这就和前文代码中的注释相呼应(缓存中若取到了bean,必须进行getObjectBeanInstance处理)。

 

     对createBean方法实际上在“Spring IOC之BeanFactory”中已经有过分析,所以流程就不再简单重复,直接按步骤:

1.  resolveBeanClass(mbd, beanName);

2.  mbd.prepareMethodOverrides();//Spring IOC之BeanFactory已有解释,不重复

3.  Object bean = resolveBeforeInstantiation(beanName, mbd);

      解释下,这里主要对于一些代理的bean做处理,我们平常经常会配置一些AOP模块,对于需要aop增强的bean实际上都会经过spring代理织入,而这些bean的代理逻辑应该就在这里处理了,具体看看这部分的代码:

/**
	 * Apply before-instantiation post-processors, resolving whether there is a
	 * before-instantiation shortcut for the specified bean.
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @return the shortcut-determined bean instance, or <code>null</code> if none
	 */
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName);
				if (bean != null) {
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
			mbd.beforeInstantiationResolved = Boolean.valueOf(bean != null);
		}
		return bean;
	}

/**
	 * Apply InstantiationAwareBeanPostProcessors to the specified bean definition
	 * (by class and name), invoking their <code>postProcessBeforeInstantiation</code> methods.
	 * <p>Any returned object will be used as the bean instead of actually instantiating
	 * the target bean. A <code>null</code> return value from the post-processor will
	 * result in the target bean being instantiated.
	 * @param beanClass the class of the bean to be instantiated
	 * @param beanName the name of the bean
	 * @return the bean object to use instead of a default instance of the target bean, or <code>null</code>
	 * @throws BeansException if any post-processing failed
	 * @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
	 */
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName)
			throws BeansException {

		for (Iterator it = getBeanPostProcessors().iterator(); it.hasNext();) {
			BeanPostProcessor beanProcessor = (BeanPostProcessor) it.next();
			if (beanProcessor instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) beanProcessor;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

//AbstractAutoProxyCreator
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, beanName) || 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;
	}

          对于AutoProxy部分代码要放到spring aop部分中去写了,这里只要明白如果是代理bean在postProcessBeforeInstantiation阶段会返回一个proxy,这时候bean已经算是实例化好了,再调用applyBeanPostProcessorsAfterInitialization即BeanPostProcessor.postProcessAfterInitialization回调进行属性的设置。最后的结果就可以返回bean对象了,只是一个Proxy Bean Object.

 

 4.  Object beanInstance = doCreateBean(beanName, mbd, args);//如果是代理bean就不会走到这一步

       解释下:对于非代理的bean,基本上实例化的逻辑就在doCreateBean这个方法了,这个方法在“Spring IOC之BeanFactory”中已经有过分析,所以不重复解释了,贴一个bean生命周期的流程图做为createBean方法的结尾:


             上图不是我所画,来源于spring IOC容器介绍。

 

       半成品出来之后还需要调用getObjectForBeanInstance进一步处理,这个方法:

protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

		// Don't let calling code try to dereference the factory if the bean isn't a factory.
		if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
		}

		// Now we have the bean instance, which may be a normal bean or a FactoryBean.
		// If it's a FactoryBean, we use it to create a bean instance, unless the
		// caller actually wants a reference to the factory.
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}

		Object object = null;
		if (mbd == null) {
			object = getCachedObjectForFactoryBean(beanName);
		}
		if (object == null) {
			// Return bean instance from factory.
			FactoryBean factory = (FactoryBean) beanInstance;
			// Caches object obtained from FactoryBean if it is a singleton.
			if (mbd == null && containsBeanDefinition(beanName)) {
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

       开始部分是逻辑检查,是否是FactoryBean,后面是从factoryBean中获取实际的Bean。获取bean也是先检查缓存,没有缓存再getObjectFromFactoryBean获取,详细再doGetObjectFromFactoryBean方法中,最后将获取的bean缓存起来。代码就不贴了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值