最近闲来无事翻阅了下spring的源码,在此记录下心得体会
spring 是一个ioc框架,我们要进行spring相关的源码阅读最好的入口就是 ClassPathXmlApplicationContext
通过以下代码正式进入spring的源码世界:
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("myApplicationContext.xml");
它的类图结构如下:
我们通过debug进入 ClassPathXmlApplicationContext 的构造方法:
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
// 调用父类构造方法
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
下面我们逐个解释每个方法
super(parent) -> AbstractXmlApplicationContext-> AbstractRefreshableConfigApplicationContext -> AbstractRefreshableApplicationContext->AbstractApplicationContext 这里一路调用父类的构造方法一直到
AbstractApplicationContext
AbstractApplicationContext的构造方法如下
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
this();
setParent(parent);
}
protected ResourcePatternResolver getResourcePatternResolver() {
//这里创建了一个处理 myApplicationContext.xml的处理器用来处理myApplicationContext.xml配置文件
return new PathMatchingResourcePatternResolver(this);
}
public void setParent(@Nullable ApplicationContext parent) {
this.parent = parent;
//因为parent为空所以进不来
if (parent != null) {
Environment parentEnvironment = parent.getEnvironment();
if (parentEnvironment instanceof ConfigurableEnvironment) {
getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
}
}
}
setConfigLocations(configLocations) -> AbstractRefreshableConfigApplicationContext
public void setConfigLocations(@Nullable String... locations) {
if (locations != null) {
Assert.noNullElements(locations, "Config locations must not be null");
this.configLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) {
// 解析myApplicationContext.xml 这个路径并把它赋值给 AbstractRefreshableConfigApplicationContext 的private String[] configLocations 这个数组变量
this.configLocations[i] = resolvePath(locations[i]).trim();
}
}
else {
this.configLocations = null;
}
}
protected String resolvePath(String path) {
return getEnvironment().resolveRequiredPlaceholders(path);
}
getEnvironment()-> AbstractApplicationContext
public ConfigurableEnvironment getEnvironment() {
if (this.environment == null) {
这里会加载相关的环境对象并赋值给 AbstractApplicationContext 的 private ConfigurableEnvironment environment 对象
this.environment = createEnvironment();
}
return this.environment;
}
protected ConfigurableEnvironment createEnvironment() {
return new StandardEnvironment();
}
// StandardEnvironment 里面包含了 systemEnvironment 与 systemProperties 这两个对象
public class StandardEnvironment extends AbstractEnvironment {
/** System environment property source name: {@value}. */
public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";
/** JVM system properties property source name: {@value}. */
public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";
/**
* Customize the set of property sources with those appropriate for any standard
* Java environment:
* <ul>
* <li>{@value #SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME}
* <li>{@value #SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME}
* </ul>
* <p>Properties present in {@value #SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME} will
* take precedence over those in {@value #SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME}.
* @see AbstractEnvironment#customizePropertySources(MutablePropertySources)
* @see #getSystemProperties()
* @see #getSystemEnvironment()
*/
@Override
protected void customizePropertySources(MutablePropertySources propertySources) {
propertySources.addLast(
new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));
propertySources.addLast(
new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));
}
}
refresh() -> AbstractApplicationContext 这个方法算是spring的最核心的方法了,下一章进行解读