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); }