Spring3.x源码分析(5)-bean加载1-总体分析

Spring3.x源码分析(5)-bean加载

《Spring源码深度解析》
spring-framework-reference

bean的加载

经过前面的分析,我们终于结束了对XML配置文件的解析,接下来对bean的加载过程进行分析。
bean的加载功能实现远比bean的解析要复杂的多,对于加载bean功能,在Spring的调用方式为:

BookService bookService = factory.getBean("bookService", BookService.class);
这行代码的执行过程是怎么样的呢? 我们先行回顾下BeanFactory的类图:
在这里插入图片描述

总体结构

getBean()的直接实现类在AbstractBeanFactory中实现的,通过一系列的重载方法,最终调用了doGetBean来进行创建。

//org.springframework.beans.factory.support.AbstractBeanFactory
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
   //---------------------------------------------------------------------
   // Implementation of BeanFactory interface
   //---------------------------------------------------------------------
   public Object getBean(String name) throws BeansException {
      return doGetBean(name, null, null, false);
   }

   public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
      return doGetBean(name, requiredType, null, false);
   }

   public Object getBean(String name, Object... args) throws BeansException {
      return doGetBean(name, null, args, false);
   }
   
   protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
		//1.提取对应的beanName
		final String beanName = transformedBeanName(name);
		Object bean;
       	 
         //2. 尝试从缓存中获取或者从singletonFactories中的ObjectFactory中获取
		Object sharedInstance = getSingleton(beanName);
		if (sharedInstance != null && args == null) {
            //3.返回对应的实例,并不是直接返回实例本身,而是需要执行指定的方法之后才能返回。
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		} else {
            //4. 只有单例模式下才会尝试解决循环依赖
            // prototype模式,不允许循环依赖
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            BeanFactory parentBeanFactory = getParentBeanFactory();
            //如果beanDefinitionMap中不包含beanName,则需要调用父类容器来获取
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                //将alias转换为最初的 beanName ,如果name以"&"开始,最终仍然要保留"&"
                String nameToLookup = originalBeanName(name);
                
                //调用父类容器的的getBean方法.
                if (args != null) {
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                } else {
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }
			
            //typeCheckOnly: 仅类型检查
            //当为false时,需要记录
            if (!typeCheckOnly) {
                //5.
                markBeanAsCreated(beanName);
            }

            try {
                //6. 将GeneranicBeanDefinition转换为 RootBeanDefinition
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

                // 保证创建beanName时,它所有的depends-on bean都已经先创建完成
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dependsOnBean : dependsOn) {
                        //循环创建依赖bean
                        getBean(dependsOnBean);
                        
                        //7. 缓存依赖bean
                        registerDependentBean(dependsOnBean, beanName);
                    }
                }

                //完成上述一系列的验证之后,接下来开始创建bean 
                
                if (mbd.isSingleton()) {
                    //8. 单例模式创建bean
                    sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
                        public Object getObject() throws BeansException {
                            try {
                                return createBean(beanName, mbd, args);
                            } catch (BeansException ex) {
                                destroySingleton(beanName);
                                throw ex;
                            }
                        }
                    });
                    //--- 同 3
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                } else if (mbd.isPrototype()) {
                    //9. prototype 模式创建bean,
                    Object prototypeInstance = null;
                    try {
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    } finally {
                        afterPrototypeCreation(beanName);
                    }
                    //--- 同 3
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                } else {
                    //10. 其他scope模式创建
                    String scopeName = mbd.getScope();
                    final Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope" + scopeName);
                    }
                    Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>(){ 
                        public Object getObject() throws BeansException {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            } finally {
                                afterPrototypeCreation(beanName);
                            }
                        }
                    });
                    //同 3
                    bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                }
            }  catch (BeansException ex) {
                // 同 5 
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }
		
       	//11. 检查所需类型是否与实际bean实例的类型匹配。
		if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
			return getTypeConverter().convertIfNecessary(bean, requiredType);
		}
		return (T) bean;
	}
}

1. 转换对应beanName

  • 去除FactoryBean的修饰符
    • 使用FactoryBean.getBean("&xxx")获得的将是FactoryBean对象
    • 使用Factory.getBean(“xxx”)且xxx对应的是FactoryBean,则返回的是FactoryBean.getObject();

BeanFactory和FactoryBean的区别

BeanFactory: 以Factory结尾,它是用于管理、生产Bean的一个工

FacotryBean: 以Bean结尾,表示它是一个特殊的Bean

  • 获取alias所表示的最终beanName

2. 尝试从缓存中加载单例

//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    /**缓存 singleton objects: bean name --> bean instance */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(64);
    /**缓存singleton factories: bean name --> ObjectFactory(这里的value是ObjectFactory,最终调用ObjectFactory.getObject()获得初始状态的bean) */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<String, ObjectFactory<?>>(16);
    
    /**缓存 early singleton objects: bean name --> bean instance */
	private final Map<String, Object> earlySingletonObjects = new HashMap<String, Object>(16);
    
    /**记录当前正在创建中的bean name (using a ConcurrentHashMap as a Set),当创建完毕时移除 */
	private final Map<String, Boolean> singletonsCurrentlyInCreation = new ConcurrentHashMap<String, Boolean>(16);
    
    public Object getSingleton(String beanName) {
        return getSingleton(beanName, true);
    }
    
    //allowEarlyReference : 是否允许早期依赖
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
        //1.检查单例缓存中是否存在实例,直接返回
        Object singletonObject = this.singletonObjects.get(beanName);
        //如果单例缓存汇总不存在 && 当前没有正在创建
        if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
            synchronized (this.singletonObjects) {
                singletonObject = this.earlySingletonObjects.get(beanName);
                if (singletonObject == null && allowEarlyReference) {
                    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
                    if (singletonFactory != null) {
                        //调用factoryBean.getObject()获取实例 
                        singletonObject = singletonFactory.getObject();
                        
                        //将factoryBean放置到earlySingletonObjects中,后续的操作中都直接使用singletonObject,而不再次使用singletonFactory
                        this.earlySingletonObjects.put(beanName, singletonObject);
                        
                        //将singletonFactory从缓存中移除。
                        this.singletonFactories.remove(beanName);
                    }
                }
            }
        }
        return (singletonObject != NULL_OBJECT ? singletonObject : null);
    }
    
    //beanName是否正在创建中
    public boolean isSingletonCurrentlyInCreation(String beanName) {
		return this.singletonsCurrentlyInCreation.containsKey(beanName);
	}
}

3. bean的实例中获取对象

doGetBean()方法中,getObjectForBeanInstance是个高频率使用的方法,无论是从缓存中获取,还是根据不同的scope策略加载,在获取bean实例之后要做的第一件事就是调用getObjectForBeanInstance来检测一下正确性,它的作用其实是检测bean是否为FactoryBean,如果是则需要调用FactoryBean.getObject()作为返回值。

//org.springframework.beans.factory.support.AbstractBeanFactory
protected Object getObjectForBeanInstance(
      Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {

   //如果name以 “&”为前缀,但是不是FactoryBean 直接抛出异常
   if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
      throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
   }

  //如果不是FactoryBean 或者 name没有以 “&”为前缀,直接返回自身
   if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
      return beanInstance;
   }
    
    //之后的逻辑即满足了: name以“&”为前缀,且 是FactoryBean 
    
   Object object = null;
   if (mbd == null) {
      //从缓存中获取由FactoryBean创建的Object, beanName为FactoryBean的name
      object = getCachedObjectForFactoryBean(beanName);
   }
   if (object == null) {
      FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
      // 将存储XML配置文件的GenericBeanDefinition转换为RootBeanDefinition
      if (mbd == null && containsBeanDefinition(beanName)) {
         mbd = getMergedLocalBeanDefinition(beanName);
      }
       
      //synthetic:合成的,用户定义的bean都为false,AOP自动创建的会为true
      boolean synthetic = (mbd != null && mbd.isSynthetic());
       
       //委托getObjectFromFactoryBean()获取Object
      object = getObjectFromFactoryBean(factory, beanName, !synthetic);
   }
   return object;
}

上述方法中调用了FactoryBeanRegistrySupport相关方法,最终可能会委托它来获取Object.

//org.springframework.beans.factory.support.FactoryBeanRegistrySupport
public abstract class FactoryBeanRegistrySupport extends DefaultSingletonBeanRegistry {
	/** 缓存由FactoryBeans创建的singleton objects: key是FactoryBean name --> value是object */
	private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<String, Object>(16);
	
	//1. beanName为 FactoryBean name,获取由该FactoryBean创建的object
	protected Object getCachedObjectForFactoryBean(String beanName) {
		Object object = this.factoryBeanObjectCache.get(beanName);
		return (object != NULL_OBJECT ? object : null);
	}
	
	//2. 执行factory.getObject();获取Object,并放置到缓存中
	protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
        //factory是单例 && singletonObjects缓存中包含beanName,即beanName已经创建(单状态未定) 
		if (factory.isSingleton() && containsSingleton(beanName)) {
            //getSingletonMutex() 返回 singletonObjects
			synchronized (getSingletonMutex()) {
				Object object = this.factoryBeanObjectCache.get(beanName);
				if (object == null) {
                     //3. 
					object = doGetObjectFromFactoryBean(factory, beanName);
                    
                      //再一次判断缓存中是否已经存在(由其他bean创建)
					Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
					if (alreadyThere != null) {
                         //单例模式下:如果从缓存中获取到,则直接返回缓存中的值。
						object = alreadyThere;
					} else {
                        //如果缓存中不存在,则需要向缓存中添加信息...
                        
                        //shouldPostProcess值为: !synthetic(合成的,用户定义的bean都为false,AOP自动创建的会为true)
                        if (object != null && shouldPostProcess) {
						 //4. postProcessObjectFromFactoryBean由子类AbstractAutowireCapableBeanFactory实现
                            object = postProcessObjectFromFactoryBean(object, beanName);
                        }
                        
                        //最后,将beanName -> object 添加至缓存
                        this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
					}
				}
				return (object != NULL_OBJECT ? object : null);
			}
		} else {
             //非单例模式,每次都返回新的Object
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			if (object != null && shouldPostProcess) {
				object = postProcessObjectFromFactoryBean(object, beanName);
			}
			return object;
		}
	}
    
    //3.调用 factory.getObject();,并做判断...
    private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
			throws BeanCreationException {
		Object object = factory.getObject();
		//省略,try-catch....
        
		// isSingletonCurrentlyInCreation = true 表示正在创建中,并没有创建完成
		if (object == null && isSingletonCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(
					beanName, "FactoryBean which is currently in creation returned null from getObject");
		}
		return object;
	}
}

抛开postProcessObjectFromFactoryBean逻辑,getObjectForBeanInstance从bean实例中获取对象已经完成了。

//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory
@Override
protected Object postProcessObjectFromFactoryBean(Object object, String beanName) {
	return applyBeanPostProcessorsAfterInitialization(object, beanName);
}

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
	Object result = existingBean;
    //从容器中获取BeanPostProcessor列表,for循环执行postProcessAfterInitialization方法
	for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
		result = beanProcessor.postProcessAfterInitialization(result, beanName);
		if (result == null) {
			return result;
		}
	}
	return result;
}

多知道一点:BeanPostProcessor

BeanPostProcessor接口的作用:当Spring容器对Bean进行实例化时,我们可以添加一些自定义的前置和后置逻辑处理。

接口定义

它的接口定义如下:

//org.springframework.beans.factory.config.BeanPostProcessor
public interface BeanPostProcessor {
	/**
	 * 前置处理
	 * @return	返回处理过后的bean,可以是最初的Bean或者是包装后的Bean;
	 *			如果返回null,后续的BeanPostProcessor不会被执行。
	 */
	Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
	
	//后置处理
	Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
}

配置方式

BeanPostProcessor是整个Spring容器级别的,BeanFactory 和之后需要分析的ApplicationContext对``BeanPostProcessor `·的配置方式稍有不同:

  • BeanFactory: 必须显式的添加BeanPostProcessor,
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));
factory.addBeanPostProcessor(new BeanPostProcessor() {
	//@Override 两方法 略...
});
  • ApplicationContext: 只需要将我们实现的BeanPostProcessor类,注册为普通的bean即可,ApplicationContext会自动检测在配置文件中实现了BeanPostProcessor接口的所有bean,并把它们注册为后置处理器。

各种子类&类图

常用的BeanPostProcessor有如下几种,它们的类图结构如下:

在这里插入图片描述

Spring开闭原则的表现-BeanPostProcessor扩展点-2

  • BeanPostProcessor:Bean后置处理器

    • postProcessBeforeInitialization(): 实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务
    • postProcessAfterInitialization(): 实例化、依赖注入、初始化完毕时执行.
  • InstantiationAwareBeanPostProcessor: 实例化Bean后置处理器

    • Object postProcessBeforeInstantiation(): 在实例化目标对象之前执行,可以自定义实例化逻辑,如返回一个代理对象等
    • boolean postProcessAfterInstantiation(): 通过构造函数或工厂方法实例化bean之后执行操作,但是在Spring属性人口(来自显式属性或自动装配)之前发生。如果返回false,随后的InstantiationAwareBeanPostProcessor和属性设置操作都会被跳过。
    • PropertyValues postProcessPropertyValues():完成其他定制的一些依赖注入和依赖检查等,如

    AutowiredAnnotationBeanPostProcessor执行@Autowired注解注入,CommonAnnotationBeanPostProcessor执行@Resource等注解的注入,PersistenceAnnotationBeanPostProcessor执行@PersistenceContext等JPA注解的注入,RequiredAnnotationBeanPostProcessor执行@Required注解的检查等

  • SmartInstantiationAwareBeanPostProcessor:继承InstantiationAwareBeanPostProcessor

    • predictBeanType: 预测Bean的类型,返回第一个预测成功的Class类型,如果不能预测返回null;

    当你调用BeanFactory.getType(name)时当通过Bean定义无法得到Bean类型信息时就调用该回调方法来决定类型信息;

    BeanFactory.isTypeMatch(name, targetType)用于检测给定名字的Bean是否匹配目标类型(如在依赖注入时需要使用);

    • determineCandidateConstructors: 检测Bean的构造器,可以检测出多个候选构造器,再有相应的策略决定使用哪一个
    • getEarlyBeanReference: 当正在创建A时,A依赖B,此时通过(将A作为ObjectFactory放入单例工厂中进行early expose,此处B需要引用A,但A正在创建,从单例工厂拿到ObjectFactory(其通过getEarlyBeanReference获取及早暴露Bean),从而允许循环依赖。
  • MergedBeanDefinitionPostProcessor: 合并Bean定义后置处理器。

    • postProcessMergedBeanDefinition: 执行Bean定义的合并。
  • DestructionAwareBeanPostProcessor: 销毁Bean后置处理器

    • postProcessBeforeDestruction : 销毁后处理回调方法,该回调只能应用到单例Bean .

    InitDestroyAnnotationBeanPostProcessor完成@PreDestroy注解的销毁方法调用

4. 循环依赖

Spring有三种循环依赖:

  • 构造器循环依赖 — 无法解决
<bean id="a" class="A">
    <constructor-arg index="0" ref="b"/>
</bean>

<bean id="b" class="B">
    <constructor-arg index="0" ref="c"/>
</bean>

<bean id="c" class="C">
    <constructor-arg index="0" ref="c"/>
</bean>

Sping创建“a”,首先去"当前创建bean池"查找是否当前bean正在被创建,如果没有,则继续其需要的构造器参数"b",并将“a”放到"当前创建bean池"
Sping创建“b”,首先去"当前创建bean池"查找是否当前bean正在被创建,如果没有,则继续其需要的构造器参数"c",并将“b”放到"当前创建bean池"
Sping创建“c”,首先去"当前创建bean池"查找是否当前bean正在被创建,如果没有,则继续其需要的构造器参数"a",并将“c”放到"当前创建bean池"
到此为止,Spring要去创建"a",发现“a”已经在"当前创建bean池"中了,表示循环依赖,抛出BeanCurrentlyInCreationException

  • setter循环依赖 — 只能解决singleton的循环依赖.

    对于setter注入造成的依赖,是通过Spring容器提前暴露刚完成构造器注入但未完成其他步骤(如setter注入)的bean来完成的,而且只能解决单例bean的循环依赖.通过提前暴露以个单例工厂方法,从而其他bean能引用到该bean(此逻辑在doCreateBean方法中):

addSingletonFactory(beanName, new ObjectFactory<Object>() {
  public Object getObject() throws BeansException {
      return getEarlyBeanReference(beanName, mbd, bean);
  }
});
  • prototype范围的依赖处理 ---- 无法处理. 因为Spring不缓存正在创建中的prototype的bean,因此无法提前暴露出创建中的bean.

isPrototypeCurrentlyInCreation()

//org.springframework.beans.factory.support.AbstractBeanFactory

//缓存正在创建中的prototype beanName
private final ThreadLocal<Object> prototypesCurrentlyInCreation =
			new NamedThreadLocal<Object>("Prototype beans currently in creation");

protected boolean isPrototypeCurrentlyInCreation(String beanName) {
    Object curVal = this.prototypesCurrentlyInCreation.get();
    return (curVal != null &&
            (curVal.equals(beanName) || (curVal instanceof Set && ((Set<?>) curVal).contains(beanName))));
}

protected void beforePrototypeCreation(String beanName) {
    Object curVal = this.prototypesCurrentlyInCreation.get();
    //如果当前线程没有 prototype类型bean 正在创建,则直接设置为String
    if (curVal == null) {
        this.prototypesCurrentlyInCreation.set(beanName);
    }	else if (curVal instanceof String) {
        //如果当前线程已经有prototype类型bean 正在创建,且为String, 说明在此之前只有一个prototype-bean在创建,改为Set类型,并同时保存之前的值+当前值
        Set<String> beanNameSet = new HashSet<String>(2);
        beanNameSet.add((String) curVal);
        beanNameSet.add(beanName);
        this.prototypesCurrentlyInCreation.set(beanNameSet);
    }	else {
        Set<String> beanNameSet = (Set<String>) curVal;
        beanNameSet.add(beanName);
    }
}

5. alreadyCreated

在前面分析getSingleton(beanName)方法时,我们已经知道DefaultSingletonBeanRegistry定义了诸多的如:singletonObjects,earlySingletonObjects,singletonFactories等相关缓存变量。

而在AbstractBeanFactory中也定义一个神似的变量alreadyCreated,在doGetBean方法执行过程中,markBeanAsCreated(),cleanupAfterBeanCreationFailure()也使用了该变量:

//org.springframework.beans.factory.support.AbstractBeanFactory

/**缓存已经至少创建一次的bean name */
private final Map<String, Boolean> alreadyCreated = new ConcurrentHashMap<String, Boolean>(64);

//将bean name 标记为已创建(或即将创建)
protected void markBeanAsCreated(String beanName) {
	if (!this.alreadyCreated.containsKey(beanName)) {
		this.alreadyCreated.put(beanName, Boolean.TRUE);
	}
}

//创建失败,从该缓存中移除
protected void cleanupAfterBeanCreationFailure(String beanName) {
	this.alreadyCreated.remove(beanName);
}

//指定的beanName 是否符合:缓存bean定义元数据的 条件
protected boolean isBeanEligibleForMetadataCaching(String beanName) {
    return this.alreadyCreated.containsKey(beanName);
}

6. MergedLocalBeanDefinition

继续上面的代码分析,接下来分析到了下面两行代码

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

将存在XML配置文件转换为的GenericBeanDefinition转换为RootBeanDefinition,如果指定beanName是子BeanDefinition则需要合并它的父类的属性。

getMergedLocalBeanDefinition()

//org.springframework.beans.factory.support.AbstractBeanFactory

/** 缓存记录已经merged的BeanDefinition: key是beanName, value是RootBeanDefinition */
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<String, RootBeanDefinition>(64);
	
/** 是否缓存bean元数据,或者每次访问都重新获取它 */
private boolean cacheBeanMetadata = true;

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) {
	//首先从缓存中获取
	RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
	if (mbd != null) {
		return mbd;
	}
    //如果缓存中没有,则从beanDefinitionMap中取出beanName定义的beanDefinition
	return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}

protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd) {
    return getMergedBeanDefinition(beanName, bd, null);
}

//当bean是inner bean时,则containingBd不为空;
protected RootBeanDefinition getMergedBeanDefinition(
    String beanName, BeanDefinition bd, BeanDefinition containingBd)
    throws BeanDefinitionStoreException {
    //锁定整个 mergedBeanDefinitions
    synchronized (this.mergedBeanDefinitions) {
        RootBeanDefinition mbd = null;

        // 再一次从缓存中获取
        if (containingBd == null) {
            mbd = this.mergedBeanDefinitions.get(beanName);
        }

        if (mbd == null) {
            if (bd.getParentName() == null) {
                //如果不存在parentName ,直接copy 转换。
                if (bd instanceof RootBeanDefinition) {
                    mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
                } else {
                    mbd = new RootBeanDefinition(bd);
                }
            } else {
                //如果存在 parentName, 则需要合并父类的属性
                
                BeanDefinition pbd;
                //转换parentBean 对应的beanName
                String parentBeanName = transformedBeanName(bd.getParentName());
                
                if (!beanName.equals(parentBeanName)) {
                    //如果父类还有父类会递归调用;
                    pbd = getMergedBeanDefinition(parentBeanName);
                } else {
                    //beanName.equals(parentBeanName)   --- how ??
                    if (getParentBeanFactory() instanceof ConfigurableBeanFactory) {
                        pbd = ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(parentBeanName);
                    }  else {
                        //抛出异常
                        throw new NoSuchBeanDefinitionException("略..");
                    }
                   
                }
                
                //根据父BeanDefinition创建RootBeanDefinition
                mbd = new RootBeanDefinition(pbd);
                //子类bd 覆盖父类mbd中相同的属性
                mbd.overrideFrom(bd);
            }
            

           //设置默认scope 为 singleton
            if (!StringUtils.hasLength(mbd.getScope())) {
                mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
            }

           	//当满足如下条件时, 修改mbd的scope
            if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
                mbd.setScope(containingBd.getScope());
            }

            // isCacheBeanMetadata(): 是否开启缓存元数据
            //isBeanEligibleForMetadataCaching(): 是否符合缓存元数据的条件(见第5节)
            if (containingBd == null && isCacheBeanMetadata() && isBeanEligibleForMetadataCaching(beanName)) {
                //记录缓存
                this.mergedBeanDefinitions.put(beanName, mbd);
            }
        }

        return mbd;
    }
}


public BeanDefinition getMergedBeanDefinition(String name) throws BeansException {
    String beanName = transformedBeanName(name);

    // 如果当前beanFactory不包含beanName && 当前容器的父容器是ConfigurableBeanFactory
    // 则尝试调用父类容器的同名方法.
    if (!containsBeanDefinition(beanName) && getParentBeanFactory() instanceof ConfigurableBeanFactory) {
        return ((ConfigurableBeanFactory) getParentBeanFactory()).getMergedBeanDefinition(beanName);
    }
    // 调用 getMergedLocalBeanDefinition()
    return getMergedLocalBeanDefinition(beanName);
}

checkMergedBeanDefinition()

//org.springframework.beans.factory.support.AbstractBeanFactory

protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, Object[] args)
 {
    // 如果是abstract,则不能实例化-- 报错
    if (mbd.isAbstract()) {
        throw new BeanIsAbstractException(beanName);
    }

    // args != null && mbd不是prototype,抛出异常  --- why ??
    if (args != null && !mbd.isPrototype()) {
        throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
                                               "Can only specify arguments for the getBean method when referring to a prototype bean definition");
    }
}

7.检查dependsOn

创建bean之前,它所依赖的dependsOnBean必须先行创建。并通过registerDependentBean(dependsOnBean, beanName);缓存依赖调用。

//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry

//beanName -> 所有依赖该beanName的 bean集合。  value为需要key(beanName) 的集合
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

//beanName -> 该beanName depends-on 的bean集合。 value为key依赖的 beanName的集合。
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<String, Set<String>>(64);

//beanName : 被依赖的beanName
//dependentBeanName: 源beanName
public void registerDependentBean(String beanName, String dependentBeanName) {
	//递归寻找beanName 实际对应的beanName
	String canonicalName = canonicalName(beanName);
	synchronized (this.dependentBeanMap) {
		Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);
		if (dependentBeans == null) {
			dependentBeans = new LinkedHashSet<String>(8);
			this.dependentBeanMap.put(canonicalName, dependentBeans);
		}
		//依赖beanName的 bean,添加一位成员 dependentBeanName(源beanName)
		dependentBeans.add(dependentBeanName);
	}
	synchronized (this.dependenciesForBeanMap) {
		Set<String> dependenciesForBean = this.dependenciesForBeanMap.get(dependentBeanName);
		if (dependenciesForBean == null) {
			dependenciesForBean = new LinkedHashSet<String>(8);
			this.dependenciesForBeanMap.put(dependentBeanName, dependenciesForBean);
		}
		//dependentBeanName(源beanName)  再添一项依赖项目canonicalName。
		dependenciesForBean.add(canonicalName);
	}
}

8. 创建singleton实例

9. 创建prototype实例

10. 创建其他scope实例

11. bean类型转换

在继续上述代码的分析之前,我们先行连接一下如下几个接口:


TypeConverter

//org.springframework.beans.TypeConverter

//TypeConverter接口定义类型转换方法,通常(但不必须)它的实现类也实现PropertyEditorRegistry接口 与之一起使用
//由于TypeConverter实现类 通常使用PropertyEditor来实现类型转换,而PropertyEditor不是线程安全的,所以TypeConverter也不是线程安全的。
public interface TypeConverter {
    //将value 转换为指定的 requiredType类型
    //Spring通常使用PropertyEditor.setAsText将String 转换为 目标类型
    //或者使用ConversionService()来替换PropertyEditor转换
    <T> T convertIfNecessary(Object value, Class<T> requiredType);	
    
    //转换目标的方法参数,主要用于分析泛型类型,可能是null
    <T> T convertIfNecessary(Object value, Class<T> requiredType, MethodParameter methodParam);
    
    //转换目标的field
    <T> T convertIfNecessary(Object value, Class<T> requiredType, Field field);	
}

PropertyEditorRegistrar, PropertyEditorRegistry, PropertyEditor

//org.springframework.beans.*

//PropertyEditor注册员
public interface PropertyEditorRegistrar {
	//添加PropertyEdito	//添加PropertyEditor注册器
r注册器
	void registerCustomEditors(PropertyEditorRegistry registry);
}


//PropertyEditor注册器
public interface PropertyEditorRegistry {
	//为给定的类型requiredType ,注册属性编辑器propertyEditor
	void registerCustomEditor(Class<?> requiredType, PropertyEditor propertyEditor);
	
	//为给定类型的指定属性 设置注册编辑器
	//如果propertyPath为null, 则同上面的同名方法
	void registerCustomEditor(Class<?> requiredType, String propertyPath, PropertyEditor propertyEditor);
	
	//寻找给定类型的 propertyPath 对应的属性编辑器
	//如果propertyPath为null, 则寻找给定类型的 属性编辑器
	PropertyEditor findCustomEditor(Class<?> requiredType, String propertyPath);
}


//PropertyEditor属性编辑器
public interface PropertyEditor {
	//设置(或更改)要编辑的对象. 原始类型如int,必须包装为相应的对象类型java.lang.Integer。
	 void setValue(Object value);
	 
	//通过使用给定的String值,来设置属性值。
	void setAsText(String text);
    
     Object getValue();
}

在这里插入图片描述

举个栗子

我们通过一个例子来来说明上述各个组件的功能:

  • 首先注册一个Bean
 <bean  id="mybook" class="spring.chap04.bean.Book">
  <property name="isbn" value="9527"/>
  <property name="name" value="trump传"/>
  <property name="price" value="3.1"/>
  <!-- publishDate 为java.util.Date类型 -->
  <property name="publishDate" value="2018-12-12"/>
 </bean>
  • 使用getBean
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));
Book myBook = factory.getBean( Book.class);

执行上述代码之后,会抛出异常:

Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property 'publishDate': no matching editors or conversion strategy found

修改程序

//自定义Date属性编辑器
class DatePropertyEditor extends  PropertyEditorSupport{
    @Override
    public void setAsText(String text) throws IllegalArgumentException {
        try {
            //通过重写setAsText,将text 转换为目标类型
            super.setValue(new SimpleDateFormat("yyyy-mm-dd").parse(text));
        } catch (ParseException e) {
            e.printStackTrace();
        }
    }
}

//自定义PropertyEditorRegistry
class MyPropertyEditorRegistry  implements PropertyEditorRegistrar{
    @Override
    public void registerCustomEditors(PropertyEditorRegistry registry) {
        //为Date类型 注册指定的 属性编辑器
        registry.registerCustomEditor(Date.class, new DatePropertyEditor());
    }
}

执行代码:

XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("beanFactoryTest.xml"));

//beanfactory必须显式添加PropertyEditorRegistrar
factory.addPropertyEditorRegistrar(new MyPropertyEditorRegistry());
Book myBook = factory.getBean( Book.class);

BeanFactory: 必须显式的添加PropertyEditorRegistrar,
ApplicationContext: 支持通过如下两种配置方式实现:

<!-- 方法一: 添加 customEditors-->
<bean id="datePropertyEditor" class="test.DatePropertyEditor"/>
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
    <property name="customEditors">
        <map>
        	<entry key="java.util.Date" value-ref="datePropertyEditor"/>
        </map>
    </property>
</bean>

<!-- 方法二: 添加propertyEditorRegistrars -->
  <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
      <property name="propertyEditorRegistrars">
          <list>
              <bean class="test.MyPropertyEditorRegistry"></bean>
          </list>
      </property>
</bean>

接下来接着分析最后的代码

//org.springframework.beans.factory.support.AbstractBeanFactory

protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) {
    //略,其他部分代码.....
    
    //如果requiredType 不是 bean实际类型的 超类或接口,则进入if{}逻辑。
    // Object.class.isAssignableFrom(String.class) == false
    // String.class.isAssignableFrom(Object.class) == true
    if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) 
        return getTypeConverter().convertIfNecessary(bean, requiredType);
    
    //不满足上述条件,直接转换
    return ( T ) bean; 
}
  • 首先分析下getTypeConverter()获取类型转换的相关逻辑。

getTypeConverter()

//org.springframework.beans.factory.support.AbstractBeanFactory

//使用conversionService 来替代 PropertyEditors
private ConversionService conversionService;

//用户自定义PropertyEditorRegistrars
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<PropertyEditorRegistrar>(4);
			
private TypeConverter typeConverter;

/**用户定义的PropertyEditors*/
private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<Class<?>, Class<? extends PropertyEditor>>(4);
		

public TypeConverter getTypeConverter() {
	//获取用户自定义的typeConverter,可以通过setTypeConverter来设置用户自定义typeConverter
	TypeConverter customConverter = getCustomTypeConverter();
	if (customConverter != null) {
		return customConverter;
	} 	else {
		// 如果没有用户自定义的TypeConverter,则使用默认的SimpleTypeConverter
		SimpleTypeConverter typeConverter = new SimpleTypeConverter();
		typeConverter.setConversionService(getConversionService());
		registerCustomEditors(typeConverter);
		return typeConverter;
	}
}

protected void registerCustomEditors(PropertyEditorRegistry registry) {
		PropertyEditorRegistrySupport registrySupport =
				(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
		if (registrySupport != null) {
			//设置 configValueEditorsActive标识为true
			registrySupport.useConfigValueEditors();
		}
		if (!this.propertyEditorRegistrars.isEmpty()) {
			for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
				
				//因为typeConverter是针对全局的,这里为所有的注册员PropertyEditorRegistrar ,都添加注册器PropertyEditorRegistry
				registrar.registerCustomEditors(registry);
			}
		}
		if (!this.customEditors.isEmpty()) {
			for (Map.Entry<Class<?>, Class<? extends PropertyEditor>> entry : this.customEditors.entrySet()) {
				Class<?> requiredType = entry.getKey();
				Class<? extends PropertyEditor> editorClass = entry.getValue();
				//将已有的所有属性编辑器信息,都添加到给定的typeConverter中
				registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass));
			}
		}
}
  • convertIfNecessary(bean, requiredType)

再次分析上面的类图,展示涉及相关类的部分代码:

//SimpleTypeConverter 继承 TypeConverterSupport
public class SimpleTypeConverter extends TypeConverterSupport {
	public SimpleTypeConverter() {
        //创建 typeConverterDelegate 代理对象,该代理对象持有this对象本身
        //将创建的代理对象 赋值给父类变量 typeConverterDelegate
		this.typeConverterDelegate = new TypeConverterDelegate(this);
        
        //调用TypeConverterSupport的父类PropertyEditorRegistrySupport.registerDefaultEditors()
		registerDefaultEditors();
	}
}

//TypeConverterSupport 又继承自 PropertyEditorRegistrySupport
public abstract class TypeConverterSupport extends PropertyEditorRegistrySupport implements TypeConverter {
	//属性变量,由子类赋值
	TypeConverterDelegate typeConverterDelegate;

	public <T> T convertIfNecessary(Object value, Class<T> requiredType) {
       
		return doConvert(value, requiredType, null, null);
	}
	//省略convertIfNecessary的重载方法...

	private <T> T doConvert(Object value, Class<T> requiredType, MethodParameter methodParam, Field field) {
        //最终执行typeConverterDelegate.convertIfNecessary
        if (field != null) {
            return this.typeConverterDelegate.convertIfNecessary(value, requiredType, field);
        } else {
            return this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam);
        }
	}
}


//TypeConverterDelegate由SimpleTypeConverter创建, 且持有该创建者对象
class TypeConverterDelegate {
	private final Object targetObject;
	private final PropertyEditorRegistrySupport propertyEditorRegistry;
    
	public TypeConverterDelegate(PropertyEditorRegistrySupport propertyEditorRegistry) {
		this(propertyEditorRegistry, null);
	}
	
	public TypeConverterDelegate(PropertyEditorRegistrySupport propertyEditorRegistry, Object targetObject) {
		this.propertyEditorRegistry = propertyEditorRegistry;
		this.targetObject = targetObject;
	}
	
	
	public <T> T convertIfNecessary(String propertyName, Object oldValue, Object newValue,
			Class<T> requiredType, TypeDescriptor typeDescriptor) throws IllegalArgumentException {

		Object convertedValue = newValue;
		//获取用户editors
		PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);

		ConversionService conversionService = this.propertyEditorRegistry.getConversionService();
		
	
		if (editor == null && conversionService != null && convertedValue != null && typeDescriptor != null) {
			TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue);
			TypeDescriptor targetTypeDesc = typeDescriptor;
			if (conversionService.canConvert(sourceTypeDesc, targetTypeDesc)) {
				//当editor== null,且满足后续的一系列条件时,使用conversionService.convert转换
				return (T) conversionService.convert(convertedValue, sourceTypeDesc, targetTypeDesc);
			}
		}


		if (editor != null || (requiredType != null && !ClassUtils.isAssignableValue(requiredType, convertedValue))) {
			if (requiredType != null && Collection.class.isAssignableFrom(requiredType) && convertedValue instanceof String) {
				TypeDescriptor elementType = typeDescriptor.getElementTypeDescriptor();
				if (elementType != null && Enum.class.isAssignableFrom(elementType.getType())) {
					convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue);
				}
			}
			if (editor == null) {
				//获取defaultEditors
				editor = findDefaultEditor(requiredType);
			}
			//当满足上述条件时,使用editor转换, 执行editor.setValue()...
			convertedValue = doConvertValue(oldValue, convertedValue, requiredType, editor);
		}

		//当convertedValue为String,Enum, Collection,Map,Array时,做相应处理.. 略。。

		return (T) convertedValue;
	}
}

//PropertyEditorRegistrySupport 定义了一系列的defaultEditors
public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
	//激活defaultEditors标识
	private boolean defaultEditorsActive = false;

	private boolean configValueEditorsActive = false;
	
	//ConversionService
	private ConversionService conversionService;
	
	//四种类型的 PropertyEditor -- setter()省略
	private Map<Class<?>, PropertyEditor> defaultEditors;
	private Map<Class<?>, PropertyEditor> overriddenDefaultEditors;
	private Map<Class<?>, PropertyEditor> customEditors;
	private Set<PropertyEditor> sharedEditors;
	
	public PropertyEditor getDefaultEditor(Class<?> requiredType) {
			if (!this.defaultEditorsActive) {
				return null;
			}
			//如果配置了overriddenDefaultEditors,则优先从中获取
			if (this.overriddenDefaultEditors != null) {
				PropertyEditor editor = this.overriddenDefaultEditors.get(requiredType);
				if (editor != null) {
					return editor;
				}
			}
			if (this.defaultEditors == null) {
				//获取defaultEditors
				createDefaultEditors();
			}
			return this.defaultEditors.get(requiredType);
		}
	
	private void createDefaultEditors() {
			this.defaultEditors = new HashMap<Class<?>, PropertyEditor>(64);
	
			// Simple editors, without parameterization capabilities.
			// The JDK does not contain a default editor for any of these target types.
			this.defaultEditors.put(Charset.class, new CharsetEditor());
			this.defaultEditors.put(Class.class, new ClassEditor());
			this.defaultEditors.put(Class[].class, new ClassArrayEditor());
			//省略 .......
	
			// Default instances of collection editors.
			// Can be overridden by registering custom instances of those as custom editors.
			this.defaultEditors.put(Collection.class, new CustomCollectionEditor(Collection.class));
			this.defaultEditors.put(Set.class, new CustomCollectionEditor(Set.class));
			//省略 .......
	
			// Default editors for primitive arrays.
			this.defaultEditors.put(byte[].class, new ByteArrayPropertyEditor());
			this.defaultEditors.put(char[].class, new CharArrayPropertyEditor());
	
			// The JDK does not contain a default editor for char!
			this.defaultEditors.put(char.class, new CharacterEditor(false));
			this.defaultEditors.put(Character.class, new CharacterEditor(true));
	
			// Spring's CustomBooleanEditor accepts more flag values than the JDK's default editor.
			this.defaultEditors.put(boolean.class, new CustomBooleanEditor(false));
			this.defaultEditors.put(Boolean.class, new CustomBooleanEditor(true));
	
			// The JDK does not contain default editors for number wrapper types!
			// Override JDK primitive number editors with our own CustomNumberEditor.
			this.defaultEditors.put(byte.class, new CustomNumberEditor(Byte.class, false));
			this.defaultEditors.put(Byte.class, new CustomNumberEditor(Byte.class, true));
			//省略 .......
			
	
			// Only register config value editors if explicitly requested.
			if (this.configValueEditorsActive) {
				StringArrayPropertyEditor sae = new StringArrayPropertyEditor();
				this.defaultEditors.put(String[].class, sae);
				this.defaultEditors.put(short[].class, sae);
				this.defaultEditors.put(int[].class, sae);
				this.defaultEditors.put(long[].class, sae);
			}
		}
	}
}

综上的流程图如下:

在这里插入图片描述



自此,除去最复杂的 8,9,10 创建bean实例相关内容,总体上 bean的创建流程就已经分析完毕,后续会针对 创建bean实例做详细的分析。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值