Spring IoC源码分析

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<String> 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<ApplicationEvent>();

创建一个beanFactory

ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

new DefaultListableBeanFactory(getInternalParentBeanFactory())

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

2. 入口方法

applicationContext.getBean(“dataSource”);

    原文作者:Spring Boot
    原文地址: https://blog.csdn.net/u011402896/article/details/79887090
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞