接着上文,我们可以知道bean注册的过程会调用BeanDefinitionRegistry
的registerBeanDefinition
方法,而且DefaultListableBeanFactory
既是一个BeanDefinitionRegistry
,又是一个BeanFactory
,可以猜到在一个BeanDefinition
的注册过程与Bean的生成有着很紧密的联系。
修改例子
新增一个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);
}
}
运行结果:
true
beldon.learn.ioc.sample.SimpleBean@6ed3ef1
上面代码已经剔除BeanDefinition
的加载过程,直接自定义一个BeanDefinition
让BeanDefinitionRegistry
注册,最终容器是可以正常运行的。
要想了解bean的注册过程,就得去了解下DefaultListableBeanFactory
的registerBeanDefinition
方法执行过程了。
源码跟踪
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;
}
}
跟进registerBeanDefinition
,可以看到最核心的代码就是
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
没错,spring就是把BeanDefinition
缓存在map里面的,而且这个map是ConcurrentHashMap
。
总结
从上面的代码可以总结出,BeanDefinition
的注册过程其实就是把它缓存到Map里面去。这仅仅是保存了BeanDefinition
,那什么时候初始化对象呢?
别忘了,上面代码还有个getBean
方法呢。万事具备只欠东风,来,执行下getBean
方法。
网友评论