在阅读Spring getBean的时候,发现在createBean()都是依赖于RootBeanDefinition来创建的bean.
protected <T> T doGetBean(final String name, final Class<T> requiredType,
final Object[] args, boolean typeCheckOnly) throws BeansException {
// something do before createBean
// .......
// get BeanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// createBean according to RootBeanDefinition
if(mbd.isSingleton()){
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}catch (BeansException ex) {
// destory
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if(mbd.isPrototype()) {
// 大致逻辑同上
} else {
// other scope bean, 大致逻辑和singleton/prototype一样
}
}
既然知道了bean instance都是根据BeanDefinition来创建的,那么
1. BeanDefinition是从哪里来的?
在doGetBean()中获取bean对应的BeanDefinition的语句: final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);(下面合并beanDefinition的语句暂时不管,后面有机会再说)
getMergedLocalBeanDefinition(beanName):
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName)
throws BeansException {
// Quick check on the concurrent map first, with minimal locking.
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
可以看到在AbstractBeanFactory中定义了 this.mergedBeanDefinitions来保存Merge BeanDefinition. 获取原始的beanDefinition还是通过getBeanDefinition(beanName).
getBeanDefinition(beanName) 在AbstractBeanFactory中是抽象方法, 在子类DefaultListableBeanFactory中被实现:
@Override
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);
if (bd == null) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}
最终可以看到在DefaultListableBeanFactory中是用的 beanDefinitionMap来保存的BeanDefinition的. (ps: 最终在ApplicationContext中使用的也是DefaultListableBeanFactory)
那么,DefaultListableBeanFactory中beanDefinitionMap中的数据又是从哪里来的.
通过追踪beanDefinitionMap.put的调用,可以看到beanDefainition.put()在registerBeanDefinition方法中被调用. 而这个方法是实现自BeanDefinitionRegistry的.
So, beanDefinitionMap中的beanDefinition都是通过实现自BeanDefinitionRegistry的接口中注册进来的.
通过上面的阅读,我们已经知道了beanDefinition是通过何种方式注册的以及如何被使用的, 那么: