Spring 源码剖析 三、主要逻辑代码赏析之根据bean的定义来生成bean

  上一节中将了如何通过xml文件中读取到bean的定义,链接为 Spring 二、主要逻辑代码赏析之获取bean的定义 ,这一节中,我们将会讲述读取出xml文件后,如何根据bean的定义来最终生成bean。

  首先还是来看一下

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); 

  初始的时候的refresh() 方法:

  	@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {

			// Prepare this context for refreshing.
			prepareRefresh();
			. . .
			// 此为获取一个 DefaultListableBeanFactory 的 beanFactory,并且会生成 XmlBeanDefinitionReader ,从xml文件中读出beanDefinition并放置到 beanFactory中
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();


			// Prepare the bean factory for use in this context.
			prepareBeanFactory(beanFactory);
			try {
				. . .

				//  DefaultListableBeanFactory 会在此方法中根据 BeanDefinition 去加载bean的定义。
				finishBeanFactoryInitialization(beanFactory);

				finishRefresh();
			}

			catch (BeansException ex) {
				. . .
				// Propagate exception to caller.
				throw ex;
			}

			finally {

				. . .
			}
		}
	}

可以看到 ,是在 finishBeanFactoryInitialization(beanFactory) 方法中将beanDefinition生成bean的。
下面我们看一下 DefultListableBeanFactory来获取bean的方法:

	@Override
	public void preInstantiateSingletons() throws BeansException {

		// 得到所有的bean定义的name列表
		List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

		// 遍历bean定义name的列表,得到对应的bean定义
		for (String beanName : beanNames) {

			this.logger.debug("beanName 为" + beanName);

			// 得到bean的定义
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {

				// 如果是工厂类的bean
				if (isFactoryBean(beanName)) {

					final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
					boolean isEagerInit;
					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
						isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
							@Override
							public Boolean run() {
								return ((SmartFactoryBean<?>) factory).isEagerInit();
							}
						}, getAccessControlContext());
					}
					else {
						isEagerInit = (factory instanceof SmartFactoryBean &&
								((SmartFactoryBean<?>) factory).isEagerInit());
					}

					if (isEagerInit) {


						getBean(beanName);

					}
				}
				
				// 如果不是工厂类的bean,即为普通bean,则直接调用 getBean() 方法
				else {
					getBean(beanName);
				}
			}
		}


	}

  可以看到,DefultListableBeanFactory会遍历bean的beanName,然后调用getBean(beanName)方法来获取到bean。getBean(beanName)即调用的 doGetBean() 方法来获取到bean。

	protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {

		final String beanName = transformedBeanName(name);
		Object bean;

		// doGetBean() ,这个方法主要做了两件事情:
		// 1、判断是否已存在指定beanName的bean,如果有,直接返回
		// 2、如果没有,得到其beanDefinition,然后生成bean,放到map中,再返回。


		// 从map中得到bean
		Object sharedInstance = getSingleton(beanName);
		// 如果有,那么就肯定不用生成了,直接返回
		if (sharedInstance != null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		// 发现如果没有bean,那么就得到相应的beanDefinition,然后生成bean
		else {


			// Fail if we're already creating this bean instance:
			// We're assumably within a circular reference.
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			. . .

			// 下面为获取单例bean的方法
			try {
				// 根据beanName来获取到bean的beanDefinition
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				. . .

				// 下面为创建bean的方法
				if (mbd.isSingleton()) {


					// 这里是实现了 ObjectFactory 这个接口,里面得到创建的 bean 
					// getSingleton方法会做一些处理在同步块中判断是否有无bean,如果没有,再调用回调获取到bean,并将bean放到 singletonObjects 中,也就是最后的 beanName - > bean对象 的Map
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							try {
								logger.debug(" createBean,初始化bean所要调用的方法 ");
								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);
				}

				. . .
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}

		. . . 

		return (T) bean;
	}

 createBean(String beanName, RootBeanDefinition mbd, Object[] args)方法,其调用的是  doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) 方法,我们看一下其实现:

	protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {

		// 此为真正去获取一个bean的方法,也是可以大致分为两步:
		// 1、找到其构造函数与构造函数中要传入的value,比如constructor.newInstance()。这样就然后生成bean的对象。相当于 User user = new User(xx,xx)
		// 2、对bean对象中的value进行填充 user.setName(xxx),本质上调用的是method.invoke()方法


		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {

			// 此为创建bean,但是仅仅是创建bean,里面的value不填充。因为要创建,所以 如果construction中有依赖,那么肯定要先加载 construction 中的依赖,	
            // 如果依赖是bean,那么就加载要依赖的bean
			instanceWrapper = createBeanInstance(beanName, mbd, args);

		}

		// 此为得到创建好的bean
		final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
		Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				mbd.postProcessed = true;
			}
		}

		// Eagerly cache singletons to be able to resolve circular references
		// even when triggered by lifecycle interfaces like BeanFactoryAware.
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, new ObjectFactory<Object>() {
				@Override
				public Object getObject() throws BeansException {
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}


		try {
			
			// bean创建完成后,调用下面的方法根据beanDefinition中定义的value对bean进行填充
			populateBean(beanName, mbd, instanceWrapper);
			
			if (exposedObject != null) {
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		. . .

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

  好,我们首先看一下 createBeanInstance() ,即创建bean的方法:

	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
		. . .
		// 此为判断bean的构造方法中是否需要value的注入,如果有,那么走 autowireConstructor 方法,先找到value
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null ||
				mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// 如果没有,直接走 instantiateBean ,直接生成一个bean
		return instantiateBean(beanName, mbd);
	}

  那么比如是

    <bean id="dependC" class="com.happyheng.bean.DependC">
        <constructor-arg ref="dependA"/>
    </bean>

   那么肯定需要走 autowireConstructor() ,因为构造方法里面有value需要创建。在 autowireConstructor()  中,首先去获取里面的value值

	private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
			ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {

		. . . 

		for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
			// 遍历 Constructor 参数
			if (valueHolder.isConverted()) {
				resolvedValues.addGenericArgumentValue(valueHolder);
			}
			else {
				// 得到 Constructor 参数里面的value
				Object resolvedValue =
						valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
				// 得到value之后,替换ConstructorArgumentValues.ValueHolder中的value
				ConstructorArgumentValues.ValueHolder resolvedValueHolder =
						new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
				resolvedValueHolder.setSource(valueHolder);
				resolvedValues.addGenericArgumentValue(resolvedValueHolder);
			}
		}

		return minNrOfArgs;
	}

  在获取value值的时候,有这样的方法:

	public Object resolveValueIfNecessary(Object argName, Object value) {
		// 如果value是 RuntimeBeanReference ,那么需要先获取到这个bean,即如果有,就直接拿到返回,如果没有,就创建
		if (value instanceof RuntimeBeanReference) {
			RuntimeBeanReference ref = (RuntimeBeanReference) value;
			return resolveReference(argName, ref);
		}

		. . .
		
	}

  所以如果 dependC 的构造函数中有 dependA 的话,那么需要先生成dependA这个bean,最后再生成 dependC 这个bean 。 

   dependC在获取到了所有构造函数的值后(即dependA已经生成),会在autowireConstructor() 方法的最后 调用 instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner, final Constructor<?> ctor, Object... args)  方法来传入Constructor与对应的args利用反射来生成bean。 

   至于前面所说的构造函数中没有参数的bean,比如:

<bean id="myBean" class="com.happyheng.bean.MyBean"/>

  则直接调用 instantiateBean(beanName, mbd) 方法,其调用了方法:

	@Override
	public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {

		/**
		 * @todo 
		 */
        // 使用了java的反射,先得到bean的Class的 constructor 的方法,然后直接使用 constructor 方法来生成一个bean
		if (bd.getMethodOverrides().isEmpty()) {
			Constructor<?> constructorToUse;
			synchronized (bd.constructorArgumentLock) {
				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
				if (constructorToUse == null) {

					// 得到bean的Class对象
					final Class<?> clazz = bd.getBeanClass();
					if (clazz.isInterface()) {
						throw new BeanInstantiationException(clazz, "Specified class is an interface");
					}
					try {
						if (System.getSecurityManager() != null) {
							constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
								@Override
								public Constructor<?> run() throws Exception {
									return clazz.getDeclaredConstructor((Class[]) null);
								}
							});
						}
						else {
							// 得到这个bean的 Constructor 方法
							constructorToUse =	clazz.getDeclaredConstructor((Class[]) null);
						}
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Exception ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
					}
				}
			}

			// 将 Constructor 方法传入到 BeanUtils 来直接生成一个对象即可
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			return instantiateWithMethodInjection(bd, beanName, owner);
		}
	}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章