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实例做详细的分析。