【Spring源码系列- IOC】
目录
2.创建工厂:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
一堆图预警~~~
通过测试启动类进入ApplicationContext容器
设置(解析)配置文件路径
setConfigLocations(configLocations);
-
参数configLocations格式是String[]
进入超级重要的refresh()方法
1.准备工作:prepareRefresh()
/**
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
*/
protected void prepareRefresh() {
// Switch to active.
/**
* 设置容器的启动时间
*/
this.startupDate = System.currentTimeMillis();
/**
* 容器的关闭标志位
*/
this.closed.set(false);
/**
* 容器的激活标志位
*/
this.active.set(true);
/**
* 日志记录
*/
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
// Initialize any placeholder property sources in the context environment.
/**
* 初始化属性资源(空实现 留给子类覆盖)
*/
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
/**
* 创建并获取环境对象,验证需要的属性文件是否都已经放入环境中
*/
getEnvironment().validateRequiredProperties();
/**
* 指定集合
*/
// Store pre-refresh ApplicationListeners...
/**
* 判断刷新前的应用程序监听器集合是否为空,如果为空,则将监听器添加到此集合中
*/
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
}
else {
// Reset local application listeners to pre-refresh state.
/**
* 如果不为空则清空集合元素对象
*/
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
/**
* 创建刷新前的监听事件集合
*/
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2.创建工厂:ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
先创建一个工厂,创建的工厂的名字是 DefaultListableBeanFactory
refreshBeanFactory()
自定义风格化的customizeBeanFactory(beanFactory);
这两个属性默认都是true(父类构造时赋的值)
超级重要的loadBeanDefinitions(beanFactory)
点进方法看到啥都木有,同学不要慌~~点下面就可以看到他的实现子类啦。。。
由上图可以发现,在Spring中这个方法有四个实现,选择进入哪个取决于你使用的配置方式:
-
AbstractXmlApplicationContext (org.springframework.context.support)
-
使用的是xml配置bean的选这个
-
位于spring.spring-context.main
-
-
AnnotationConfigWebApplicationContext (org.springframework.web.context.support)
-
spring.spring-web.main
-
-
GroovyWebApplicationContext (org.springframework.web.context.support)
-
spring.spring-web.main
-
-
XmlWebApplicationContext (org.springframework.web.context.support)
-
spring.spring-web main
-
由于本文是以xml配置文件为示例,故我们选择AbstractXmlApplicationContext这个类里的
loadBeanDefinitions(beanDefinitionReader)的实现
再次进入名为loadBeanDefinitions(beanDefinitionReader) 的方法中
再再次进入名为loadBeanDefinitions(configLocations) 的方法中
再再再次进入名为loadBeanDefinitions(location)的方法中
再再再再次进入名为loadBeanDefinitions(resources) 的方法中
再再再再再次进入名为loadBeanDefinitions(resources) 的方法中
进入其实现子类
选择类XmlBeanDefinitionReader
再再再再再再次进入名为loadBeanDefinitions(resources) 的方法中
doLoadBeanDefinitions(inputSource, encodedResource.getResource());
再次进入名为doLoadBeanDefinitions(inputSource, encodedResource.getResource())的方法中
doLoadDocument(InputSource inputSource, Resource resource)
getValidationModeForResource(Resource resourc)
detectValidationMode(Resource resource)
detectValidationMode(InputStream inputStream)
loadDocument()
先总结下配置参数configLocations的类型转换的过程:
String[] —> String —> Resource[] —> Resource —> document文档 —> 根据文档的节点信息封装成一个个的BeanDefinition
继续!~
registerBeanDefinitions(doc, resource);
createBeanDefinitionDocumentReader()
registerBeanDefinitions(doc, createReaderContext(resource));
doRegisterBeanDefinitions(Element root) ;
我们转换的是BeanDefinition,所以进入了BEAN_ELEMENT这个条件分支中
选择子类DefaultListableBeanFactory
下面两张图是一个函数(这个函数有点长~)
走到这里,我们见证了BeanDefinition和BeanName都被放进了相应的容器内!
/** 注册BeanDefinition*/
this.beanDefinitionMap.put(beanName, beanDefinition);
/** 记录BeanName */
this.beanDefinitionNames.add(beanName);
这篇就先到这了喽~下篇继续 >>> 努力脸.gif💪
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/135436.html