Spring bean初始化(2) - bean实例化

Spring bean初始化(2) - bean实例化

 

    XmlBeanFactory bf = new XmlBeanFactory(new ClassPathResource("/spring-code-test.xml"));
    // bean实例化是由getBean调用触发的
    TestBean bean = (TestBean) bf.getBean("testbean"); 

 上一节讲了上面的第一步,载入和解析xml,此步完成后,是将bean的定义转为BeanDefinition对象, getBean方法实际将BeanDefinition的信息进行实例化。

 

下面讲一下实例化过程

  

// AbstractBeanFactory 类
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

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;
        // 先获取当前bean,如果能获取到bean对象,
        // 或者能获取到bean对应的 ObjectFactory.getObject() 返回的对象
        // ObjectFactory.getObject() 就是为了解决单例的循环依赖问题的,后面详细说
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
            // 普通bean,此方法不做处理,如果是 FactoryBean,
            // 实际会返回 FactoryBean.getObject()返回的对象
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		} else {
			//略过 当前beanfactory没有bean的话,会查询parent beanfactory

			try {
                        // 将beanDefinition转化为RootBeanDefinition, bean的创建都是基于RootBeanDefinition的
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
				checkMergedBeanDefinition(mbd, beanName, args);

				// Guarantee initialization of beans that the current bean depends on.
				
				// 若bean没有没创建过,则开始创建bean,实际会调用ObjectFactory中getObject方法,
                                // 进而调用 createBean 方法
				if (mbd.isSingleton()) {
					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							try {
								return createBean(beanName, mbd, args);
							}
							catch (BeansException ex) {
								destroySingleton(beanName);
								throw ex;
							}
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				} 
                                // prototype类型不允许循环依赖,因为它是使用时创建,没有单例相关的缓存协助解决循环依赖
                                else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}

				else {
					String scopeName = mbd.getScope();
					final Scope scope = this.scopes.get(scopeName);
					try {
						Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
							@Override
							public Object getObject() throws BeansException {
								beforePrototypeCreation(beanName);
								try {
									return createBean(beanName, mbd, args);
								}
								finally {
									afterPrototypeCreation(beanName);
								}
							}
						});
						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
					}
				}
			}
		}

		// Check if required type matches the type of the actual bean instance.
		return (T) bean;
	}
 
对于如何解决单例模式的bean的循环依赖问题,实际是通过缓存记录解决的,假设A 依赖B, B依赖A, 创建A对象的时候,会先实例化A,然后将A的ObjectFactory对象放入缓存 singletonFactories,然后发现A的属性注入B,开始B的创建,实例化B,将B的ObjectFactory对象放入  singletonFactories, 然后发现依赖A,进行A的实例化,进入上面代码的方法 getSingleton(beanNam),此时可以得到A在 singletonFactories的对象,虽然A没有完初始化完成,但是此时A的引用已经拿到,可以继续完成B的初始化和属性注入,B完成后,继续A的依赖注入B和A的初始化。 getSingleton的代码如下
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
                // 从已经完成创建的bean对象缓存中查找,找到则返回
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			synchronized (this.singletonObjects) {
                                // 从 earlySingletonObjects 中找
				singletonObject = this.earlySingletonObjects.get(beanName);
				if (singletonObject == null && allowEarlyReference) {
                                        // 没有找到,则去 singletonFactories 找
                                        // 正在创建的对象会先将ObjectFactory放入 singletonFactories
					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
					if (singletonFactory != null) {
						singletonObject = singletonFactory.getObject();
                                                // 加入缓存,下次访问提高效率						
                                                this.earlySingletonObjects.put(beanName, singletonObject);
                                                // 这两个缓存是互斥的,上面的加了,下面这个就没用了						
                                                this.singletonFactories.remove(beanName);
					}
				}
			}
		}
		return (singletonObject != NULL_OBJECT ? singletonObject : null);
}

下面重点讲一下创建bean的过程, 即 createBean()方法的具体实现

// AbstractAutowireCapableBeanFactory 类
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)  {
try {
			// BeanPostProcessors 前置处理,可以创建代理
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		
                // 创建bean, 里面仍然可以 有 BeanPostProcessors 的代理可能
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
urn beanInstance;
}

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
                // 将 RootBeanDefinition 实例化为 BeanWrapper, 后面都是基于这个对象操作
                // instanceWrapper已经是对象地址引用了
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
                // 这一步就是为了解决循环依赖的,将bean的ObjectFactory对象放入缓存
                boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			addSingletonFactory(beanName, new ObjectFactory<Object>() {
				@Override
				public Object getObject() throws BeansException {
					return getEarlyBeanReference(beanName, mbd, bean);
				}
			});
		}
                // 属性注入和进行bean的其他初始化
		Object exposedObject = bean;
		try {
                        // 属性注入,包括bean属性注入,注入bean属性,会先实例化相应的bean
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
                                // 会调用配置的init-method方法, 
                                // 里面还会调用 BeanPostProcessors,进行处理,AOP 的代理就是在这里面触发
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}


 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值