接著上文,我們可以知道bean注冊的過程會調(diào)用BeanDefinitionRegistry的registerBeanDefinition方法,而且DefaultListableBeanFactory既是一個(gè)BeanDefinitionRegistry,又是一個(gè)BeanFactory,可以猜到在一個(gè)BeanDefinition的注冊過程與Bean的生成有著很緊密的聯(lián)系。
修改例子
新增一個(gè)BeanRegistryApplication
package beldon.learn.ioc.sample;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
public class BeanRegistryApplication {
public static void main(String[] args) throws Exception{
BeanDefinition beanDefinition = BeanDefinitionReaderUtils.createBeanDefinition(null, SimpleBean.class.getName(), BeanRegistryApplication.class.getClassLoader());
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
beanFactory.registerBeanDefinition("simpleBean", beanDefinition);
System.out.println(beanFactory.containsBean("simpleBean"));
SimpleBean bean = beanFactory.getBean(SimpleBean.class);
System.out.println(bean);
}
}
運(yùn)行結(jié)果:
true
beldon.learn.ioc.sample.SimpleBean@6ed3ef1
上面代碼已經(jīng)剔除BeanDefinition的加載過程,直接自定義一個(gè)BeanDefinition讓BeanDefinitionRegistry注冊,最終容器是可以正常運(yùn)行的。
要想了解bean的注冊過程,就得去了解下DefaultListableBeanFactory的registerBeanDefinition方法執(zhí)行過程了。
源碼跟蹤
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// hide code
if (hasBeanCreationStarted()) {
//... hide code
}
else {
// Still in startup registration phase
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
this.manualSingletonNames.remove(beanName);
}
this.frozenBeanDefinitionNames = null;
}
}
跟進(jìn)registerBeanDefinition,可以看到最核心的代碼就是
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
沒錯(cuò),spring就是把BeanDefinition緩存在map里面的,而且這個(gè)map是ConcurrentHashMap。
總結(jié)
從上面的代碼可以總結(jié)出,BeanDefinition的注冊過程其實(shí)就是把它緩存到Map里面去。這僅僅是保存了BeanDefinition,那什么時(shí)候初始化對象呢?
別忘了,上面代碼還有個(gè)getBean方法呢。萬事具備只欠東風(fēng),來,執(zhí)行下getBean方法。