obtainFreshBeanFactory()
源码:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {this.refreshBeanFactory();// 省略...}
refreshBeanFactory()
是一个抽象方法 , 有两个具体的实现类:
- AbstractRefreshableApplicationContext
- GenericApplicationContext
AbstractRefreshableApplicationContext
, 所以我们看在这个类中 refreshBeanFactory()
的实现:protected final void refreshBeanFactory() throws BeansException {//...try {DefaultListableBeanFactory beanFactory = this.createBeanFactory(); // 1beanFactory.setSerializationId(this.getId());this.customizeBeanFactory(beanFactory);this.loadBeanDefinitions(beanFactory);// 2///...}}
我们抽出这两行代码进行分析:- 创建 BeanFactory , 以 DefaultListableBeanFactory 作为 IoC 容器 。
- BD 的载入相关启动 。
loadBeanDefinitions()
进行进一步分析 。该方法调用的是本类的一个抽象方法loadBeanDefinitions(DefaultListableBeanFactory var1)
, 此方法是模板方法 , 由子类具体实现:
文章插图
而 FSXAC 就是
AbstractXmlApplicationContext
的子类 , 所以进而分析这个类的具体实现 。
文章插图
可以看到:
- 创建了 XmlBeanDefinitionReader 类 , 用于将 XML 文件中的 Bean 读取出来并加载 。
- 调用 XBDR 的 loadBeanDefinitions , 开始启动 BeanDefinition 的加载 。
- 在具体的实现中 , 分别传入不同的参数 , 但是在此方法中走判断时 , 调用了
this.getConfigResources()
这个方法在此类中是返回的Resource[]
是 null , 所以走第二个判断 , 获取以字符串数组 , 因为之前在 FSXAC 中就设置好了 。
文章插图
String[]
传入调用的是 XmlBeanDefinitionReader
的基类 AbstractBeanDefinitionReader
的方法:
文章插图
这里就是将 String 数组中的字符串 , 一个一个传入调用本类重载方法 , 并且对其进行计数 。
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {return this.loadBeanDefinitions(location, (Set)null);}public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException {// 取得 ResourceLoader , 使用的是 DeaultResourceLoaderResourceLoader resourceLoader = this.getResourceLoader(); // 关键代码1if (resourceLoader == null) {//...略} else {int loadCount;// 调用 DefaultResourceLoader 的 getResource 完成具体的 Resource 定位if (!(resourceLoader instanceof ResourcePatternResolver)) { // 关键代码2Resource resource = resourceLoader.getResource(location);loadCount = this.loadBeanDefinitions((Resource)resource);//... 略} else {// 调用 DefaultResourceLoader 的 getResources 完成具体的 Resource 定位try {Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);loadCount = this.loadBeanDefinitions(resources);//... 略}//... 略}}}
可以看到最终调用的是两个参数的方法:(String location, Set<Resource> actualResources)
, 通过上面代码的简要分析 , 我们提取出两个重要的信息:
经验总结扩展阅读
- Shell揭秘——程序退出状态码
- 基于PL022 SPI 控制器 海思3516系列芯片SPI速率慢问题深入分析与优化
- 六部恋爱甜甜电影推荐——冬天到了 一起恋爱吧 1. 这部电影也太好看了
- 0025:2011年NOIp普及组真题——瑞士轮题解
- 4 .NET 6学习笔记——如何在.NET 6的Desktop App中使用Windows Runtime API
- 学习ASP.NET Core Blazor编程系列八——数据校验
- 1 Redis—问题
- 豆芽煮多久能熟
- 之四 2流高手速成记:SpringBoot整合redis及mongodb
- 自己动手写线程池——向JDK线程池进发