《Spring技术内幕》学习笔记2——IoC定位Bean定义资源 .

本文深入探讨了Spring IoC容器初始化的过程,包括Bean定义资源文件的定位、载入和注册三个基本步骤。通过分析FileSystemXmlApplicationContext的源代码,详细阐述了如何在创建容器时定位并载入Bean定义资源文件,以及容器初始化时的具体实现过程。

1.IoC容器初始化:

Spring的IoC容器初始化包括:Bean定义资源文件的定位、载入和注册3个基本过程。

(1).Bean定义资源文件的定位:

Bean定义资源文件定位由ResourceLoader通过统一的Resource接口来完成,Resource接口将各种形式的Bean定义资源文件封装成统一的、IoC容器可进行载入操作的对象。

(2).Bean定义资源文件的载入:

Bean定义资源文件载入的过程是将Bean定义资源文件中配置的Bean转换成IoC容器中所管理Bean的数据结构形式。SpringIoC中管理的Bean的数据结构是BeanDefinition,BeanDefinition是POJO对象在IoC容器中的抽象。

(3).Bean定义的注册:

通过调用BeanDefinitionRegistry接口把从Bean定义资源文件中解析的Bean向IoC容器进行注册,在IoC容器内部,是通过一个HashMap来存储这些Bean对象数据的。

注意:IoC容器和上下文初始化一般不包含Bean依赖注入的实现。一般而言,依赖注入发送在应用第一次通过getBean方法向容器获取Bean时。但是有个特例是:IoC容器预实例化配置的lazyinit属性,如果某个Bean设置了lazyinit属性,则该Bean的依赖注入在IoC容器初始化时就预先完成了。

 

2.Bean定义资源文件的定位过程:

ApplicationContext是一个在BeanFactory基础上提供了扩展的接口,具体的IoC容器实现常用的有:(从文件系统中读入Bean定义资源文件)、ClassPathXmlApplicationContext(从Classpath类路径中读入Bean定义资源文件)和XmlWebApplicationContext(从Web容器如Tomcat等中读入Bean定义资源文件)等。以FileSystemXmlApplicationContet为例,通过分析FileSystemXmlApplicationContet及其父类的源码来分析IoC容器定位Bean定义资源文件的实现过程

3. FileSystemXmlApplicationContet的初始化过程:

FileSystemXmlApplicationContet的源码如下:

  1. public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext {  
  2.       
  3.     public FileSystemXmlApplicationContext() {  
  4.     }  
  5.     public FileSystemXmlApplicationContext(ApplicationContext parent) {  
  6.         super(parent);  
  7.     }  
  8.     //configLocation是Bean定义资源文件路径   
  9.     public FileSystemXmlApplicationContext(String configLocation) throws BeansException {  
  10.         this(new String[] {configLocation}, true, null);  
  11.     }  
  12.     //可以传入多个Bean定义资源文件路径   
  13.     public FileSystemXmlApplicationContext(String... configLocations) throws BeansException {  
  14.         this(configLocations, true, null);  
  15.     }  
  16.     public FileSystemXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException {  
  17.         this(configLocations, true, parent);  
  18.     }  
  19.     public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh) throws BeansException {  
  20.         this(configLocations, refresh, null);  
  21.     }  
  22. //FileSystemXmlApplicationContext IoC容器进行初始化的入口构造函数   
  23.     public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)  
  24.             throws BeansException {  
  25.         super(parent);  
  26. //调用父类AbstractRefreshableConfigApplicationContext的方法,设置//Bean定义的资源文件,完成IoC容器Bean定义资源的定位   
  27.         setConfigLocations(configLocations);  
  28.         if (refresh) {  
  29. //调用父类AbstractApplicationContext的refresh()   
  30. //函数启动载入Bean定义的过程,是Ioc容器载入Bean定义的入口   
  31.             refresh();  
  32.         }  
  33.     }  
  34. //该方法覆盖父类DefaultResourceLoader的方法,通过Bean定义文件路径封装得到//IoC容器要读入的定位Bean定义的资源   
  35.     @Override  
  36.     protected Resource getResourceByPath(String path) {  
  37.         if (path != null && path.startsWith("/")) {  
  38.             path = path.substring(1);  
  39.         }  
  40. //其他类型的IoC容器会用其他类型的Resource来定位Bean定义,如//ClasspathResource等   
  41.         return new FileSystemResource(path);  
  42.     }  
  43. }  
 

 

通过分析FileSystemXmlApplicationContext的源代码可以知道,在创建FileSystemXmlApplicationContext容器时,构造方法做以下两项重要工作:

首先,调用父类容器的构造方法(super(parent)方法)为容器设置好Bean资源加载器。

然后,再调用父类AbstractRefreshableConfigApplicationContext的setConfigLocations(configLocations)方法设置Bean定义资源文件的定位路径。

4. FileSystemXmlApplicationContext调用父类构造方法所做的工作:

 

通过追踪FileSystemXmlApplicationContext的继承体系,发现其父类的父类AbstractApplicationContext中初始化IoC容器所做的主要源码如下:

  1. public abstract class AbstractApplicationContext extends DefaultResourceLoader  
  2.         implements ConfigurableApplicationContext, DisposableBean {  
  3. //静态初始化块,在整个容器创建过程中只执行一次   
  4. static {  
  5.         //为了避免应用程序在Weblogic8.1关闭时出现类加载异常加载问题,加载IoC容   
  6. //器关闭事件(ContextClosedEvent)类   
  7.         ContextClosedEvent.class.getName();  
  8.     }  
  9.     //FileSystemXmlApplicationContext调用父类构造方法调用的就是该方法   
  10.     public AbstractApplicationContext(ApplicationContext parent) {  
  11.         this.parent = parent;  
  12.         this.resourcePatternResolver = getResourcePatternResolver();  
  13.     }  
  14. //获取一个Spring Source的加载器用于读入Spring Bean定义资源文件   
  15. protected ResourcePatternResolver getResourcePatternResolver() {  
  16.         // AbstractApplicationContext继承DefaultResourceLoader,也是一个S   
  17.         //Spring资源加载器,其getResource(String location)方法用于载入资源   
  18.         return new PathMatchingResourcePatternResolver(this);  
  19.     }   
  20. ……  
  21. }  
 

 

5. AbstractApplicationContext构造方法中调用PathMatchingResourcePatternResolver的构造方法创建Spring资源加载器:

 

PathMatchingResourcePatternResolver的构造方法如下:

  1. public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {  
  2.         Assert.notNull(resourceLoader, "ResourceLoader must not be null");  
  3.         //设置Spring的资源加载器   
  4.         this.resourceLoader = resourceLoader;  
  5.     }  
 

 

在设置容器的资源加载器之后,接下来FileSystemXmlApplicationContet执行setConfigLocations方法调用父类其类的相关方法定位Bean定义资源文件。

6. AbstractRefreshableConfigApplicationContext定位Bean定义资源文件:

在对FileSystemXmlApplicationContet的源码分析中我们看到,在其入口构造函数中,通过调用其父类AbstractRefreshableConfigApplicationContext的方法进行对Bean定义资源文件的定位,该方法的源码如下:

  1. //处理单个资源文件路径为一个字符串的情况   
  2. public void setConfigLocation(String location) {  
  3. //String CONFIG_LOCATION_DELIMITERS = ",; /t/n";   
  4. //即多个资源文件路径之间用” ,; /t/n”分隔,解析成数组形式   
  5.         setConfigLocations(StringUtils.tokenizeToStringArray(location, CONFIG_LOCATION_DELIMITERS));  
  6.     }  
  7.     //解析Bean定义资源文件的路径,处理多个资源文件字符串数组   
  8.     public void setConfigLocations(String[] locations) {  
  9.         if (locations != null) {  
  10.             Assert.noNullElements(locations, "Config locations must not be null");  
  11.             this.configLocations = new String[locations.length];  
  12.             for (int i = 0; i < locations.length; i++) {  
  13.                 // resolvePath为同一个类中将字符串解析为路径的方法   
  14.                 this.configLocations[i] = resolvePath(locations[i]).trim();  
  15.             }  
  16.         }  
  17.         else {  
  18.             this.configLocations = null;  
  19.         }  
  20.     }  
 

 

 

 

 

通过这两个方法的源码我们可以看出,我们既可以使用一个字符串来配置多个Spring Bean定义资源文件,也可以使用字符串数组,即下面两种方式都是可以的:

a.    ClasspathResource res = new ClasspathResource(“a.xml,b.xml,……”);

多个资源文件路径之间可以是用” ,; /t/n”等分隔。

b.    ClasspathResource res = new ClasspathResource(newString[]{“a.xml”,”b.xml”,……});

至此,Spring IoC容器在初始化时将配置的Bean定义资源文件定位为Spring封装的Resource。

内容概要:本文以一款电商类Android应用为案例,系统讲解了在Android Studio环境下进行性能优化的全过程。文章首先分析了常见的性能问题,如卡顿、内存泄漏和启动缓慢,并深入探讨其成因;随后介绍了Android Studio提供的三大性能分析工具——CPU Profiler、Memory Profiler和Network Profiler的使用方法;接着通过实际项目,详细展示了从代码、布局、内存到图片四个维度的具体优化措施,包括异步处理网络请求、算法优化、使用ConstraintLayout减少布局层级、修复内存泄漏、图片压缩与缓存等;最后通过启动时间、帧率和内存占用的数据对比,验证了优化效果显著,应用启动时间缩短60%,帧率提升至接近60fps,内存占用明显下降并趋于稳定。; 适合人群:具备一定Android开发经验,熟悉基本组件和Java/Kotlin语言,工作1-3年的移动端研发人员。; 使用场景及目标:①学习如何使用Android Studio内置性能工具定位卡顿、内存泄漏和启动慢等问题;②掌握从代码、布局、内存、图片等方面进行综合性能优化的实战方法;③提升应用用户体验,增强应用稳定性与竞争力。; 阅读建议:此资源以真实项目为背景,强调理论与实践结合,建议读者边阅读边动手复现文中提到的工具使用和优化代码,并结合自身项目进行性能检测与调优,深入理解每项优化背后的原理。
内容概要:本文系统阐述了无人机在建筑行业全生命周期的应用及生产建厂的选址策略。涵盖从规划勘察、施工管理、特殊作业到运维巡检的全流程应用场景,详细介绍了无人机在测绘、质量检测、安全管理、物料运输等方面的高效解决方案,并提供硬件选型、实施流程、数据处理与BIM集成的技术路径。同时,分析了无人机应用带来的效率提升、成本节约与安全升级等核心优势,并提出分阶段实施策略与合规风险规避措施。此外,文章还深入探讨了无人机生产建厂的选址要素,依据研发型、制造型等不同定位,推荐珠三角、长三角、皖江城市带、成渝地区等重点区域,结合供应链、政策、人才、物流等因素进行量化评估,提供实操性选址方法与风险防控建议。; 适合人群:建筑企业管理人员、工程技术人员、智慧工地建设者、无人机应用开发者及有意投资无人机生产制造的相关企业和决策者; 使用场景及目标:①指导建筑项目全过程引入无人机技术以提升效率、降低成本、强化安全;②为企业布局无人机研发或生产基地提供科学选址与投资决策依据; 阅读建议:此资源兼具技术应用与产业布局双重价值,建议结合具体项目需求或投资计划,分模块精读并制定落地行动计划,重点关注技术选型匹配性与选址要素权重分析。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值