Spring IoC源码分析

扫码关注公众号:Java 技术驿站

发送:vip
将链接复制到本浏览器,永久解锁本站全部文章

【公众号:Java 技术驿站】 【加作者微信交流技术,拉技术群】
免费领取10G资料包与项目实战视频资料

Spring IOC容器源码分析

  1. 入口类

new ClassPathXmlApplicationContext(“spring.xml”);

直接采用读取classpath路径下xml的容器类

这个类依赖于xml文件的配置,同时需要的jar包是 context core 和 beans

分工:

context 负责容器

beans 负责根据xml注册的bean,也包括了注解注入注册的bean

core 一些工具类

1.1 new的时候发生了什么?spring做了哪些操作。

(1) 根据spring.xml名称初始化configLocation = spring.xml 构建一个数组

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {

this(new String[] {configLocation}, true, null);

}

如果有多个配置文件,就自动构成一个加长数组

public ClassPathXmlApplicationContext(String… configLocations) throws BeansException {

this(configLocations, true, null);

}

将所有的初始化委托给了有参构造器

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)

throws BeansException {

super(parent);

setConfigLocations(configLocations);

if (refresh) {

refresh();

}

}

a.递归调用父类构造器

a1. 得到类加载器,依次是当前线程的类加载器Thread.currentThread.getContextLoader(),

加载委托类的加载器 ClassUtils.class.getClassLoader(),系统加载器ClassLoader.getSystemClassLoader

a2. 得到一个new PathMatchingResourcePatternResolver(this) 路径资源解析

a3. setParent(parent); 设置父类容器,null就没有了

b. 加载路径数组 setConfigLocations(configLocations);

b1. 取一个同样长度的数组,解析,返回字符串

this.configLocations[i] = resolvePath(locations[i]).trim();

b2. 创建了一个标准的环境对象 new StandardEnvironment();

getEnvironment().resolveRequiredPlaceholders(path);

b3. 委托给环境对象中的属性解析器进行解析 ConfigurablePropertyResolver 解析对象

this.propertyResolver.resolveRequiredPlaceholders(text);

b4. 创建了一个helper对象解析

public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {

if (this.strictHelper == null) {

this.strictHelper = createPlaceholderHelper(false);

}

return doResolvePlaceholders(text, this.strictHelper);

}

b5. 一路跟踪,调用这个方法,第二个参数回调函数(策略模式?)

protected String parseStringValue(

String value, PlaceholderResolver placeholderResolver, Set visitedPlaceholders)

打算用一个while循环来解析 value = spring.xml, 但这里的前缀是 ${ 为-1直接返回了”spring.xml” 字符串

StringBuilder result = new StringBuilder(value);

int startIndex = value.indexOf(this.placeholderPrefix);

while (startIndex != -1) {

——————–以上啥都没干—————

还是做了,初始化了解析对象,环境对象等,下面是一个刷新方法。应该就是其主要逻辑了。

if (refresh) {

refresh();

}

b6. synchronized (this.startupShutdownMonitor) { 要初始化需要加互斥锁

准备工作包含了开始时间戳,活动boolean true,关闭false,空的初始化属性。

// Prepare this context for refreshing.

prepareRefresh();

校验属性有没有异常,有的话会抛出,中止

getEnvironment().validateRequiredProperties();

用来存储更早的应用事件

this.earlyApplicationEvents = new LinkedHashSet();

创建一个beanFactory

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

new DefaultListableBeanFactory(getInternalParentBeanFactory())

在该beanFactory中注册加载类,忽略的类,等

  1. 入口方法

applicationContext.getBean(“dataSource”);


来源:[]()

赞(0) 打赏
版权归原创作者所有,任何形式的转载请联系博主:daming_90:Java 技术驿站 » Spring IoC源码分析

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏