总结一句话:?告诉子类刷新内部bean工厂,读取xml文件,并解析出来,注入到beanfactory里面去。
进入到obtainFreshBeanFactory可看到有两个方法:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
我们先研究refreshBeanFactory()方法:
/**
此实现执行此上下文的底层 bean 工厂的实际刷新,关闭先前的 bean 工厂(如果有)并为上下文生命周期的下一个阶段初始化一个新的 bean 工厂。
*/
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) { //如果存在了beanfactory,则关闭掉,
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
//为了序列号指定id,可以从id防序列号化到beanFactory对象
//id的值是在super()方法中进行设值的,这里只是单纯的获取id ,详细见
https://blog.csdn.net/u012249177/article/details/81008334?spm=1001.2014.3001.5501
beanFactory.setSerializationId(getId());
//定制beanfactory,设置相关属性,包括是否允许覆盖同名陈的不同定义的对象以及循环依赖
customizeBeanFactory(beanFactory);
//初始化documentReader,并进行xml文件解读及解析
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
然后到 里面重点的类:??customizeBeanFactory定制化beanfactory
自定义此上下文使用的内部 bean 工厂。 每次refresh()尝试时调用。
如果指定,默认实现应用此上下文的“allowBeanDefinitionOverriding”和“allowCircularReferences”设置。 可以在子类中覆盖以自定义DefaultListableBeanFactory的任何设置。
参数:
beanFactory – 为此上下文新创建的 bean 工厂
也可以看看:
DefaultListableBeanFactory.setAllowBeanDefinitionOverriding , DefaultListableBeanFactory.setAllowCircularReferences , DefaultListableBeanFactory.setAllowRawInjectionDespiteWrapping , DefaultListableBeanFactory.setAllowEagerClassLoading
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
//如果属性allowBeanDefinitionOverriding 不为空,则设置给beanfactory对象相应属性,是否允许覆盖同名称的不同定义的对象。
if (this.allowBeanDefinitionOverriding != null) {
//如果属性allowBeanDefinitionOverriding不为空,则设置给beanfactory对象相应属性,是否bean存在循环依赖 beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
例如我们使用重写父类的方法:
@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
super.setAllowBeanDefinitionOverriding(false);
super.setAllowCircularReferences(false);
//super.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
super.customizeBeanFactory(beanFactory);
}
然后看下代码执行顺序, 先子类设置这两个属性为false,然后再父类的方:
然后执行到父类的方法:
我们到了最后的一个方法:loadBeanDefinitions
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
// 以Resource的方式获得配置文件的资源位置
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
// 以String的形式获得配置文件的位置 ,此处在外面进行了setconfigLoaction的设置,此处为单纯的获取
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
loadBeanDefinitions:?
// 此处获取xml文件的document对象,这个解析过程是由documentLoader完成的,从String[] -string-Resource[]- resource,最终开始将resource读取成一个document文档,根据文档的节点信息封装成一个个的BeanDefinition对象
Document doc = doLoadDocument(inputSource, resource);
//这里是解析document,并将解析后的参数放到beanfacotory中
int count = registerBeanDefinitions(doc, resource);
解析的最终代码:
?
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// beanDefinitionHolder是beanDefinition对象的封装类,封装了BeanDefinition,bean的名字和别名,用它来完成向IOC容器的注册
// 得到这个beanDefinitionHolder就意味着beandefinition是通过BeanDefinitionParserDelegate对xml元素的信息按照spring的bean规则进行
// 解析得到的
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
// 向ioc容器注册解析得到的beandefinition的地方
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
// 在beandefinition向ioc容器注册完成之后,发送消息
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
?
// Still in startup registration phase
// 注册beanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
// 记录beanName
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
?
|