开始进入spring
ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
application.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.mashibing"></context:component-scan>
<bean id="person" class="com.mashibing.Person">
<constructor-arg name="id" value="1"></constructor-arg>
<constructor-arg name="name" value="lisi"></constructor-arg>
</bean>
</beans>
通过new ClassPathXmlApplicationContext会调用构造方法
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {}
/**
* 创建一个新的ClassPathXmlApplicationContext,从xml文件中加载给定的bean定义信息,并且刷新上下文
*/
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
//调用下面的构造方法,此处3个参数
this(new String[] {configLocation}, true, null);
}
//传递过来的configLocations空数组,refresh为true,parent为null
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh,
@Nullable ApplicationContext parent)
throws BeansException {
// 一、调用父类构造方法,进行相关的对象创建等操作,包含属性的赋值操作
super(parent);
// 二、
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
一、super(parent)父类构造方法
//parent参数为null
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
//调用本类无参构造
this();
setParent(parent);
}
this():AbstractApplicationContext类
AbstractApplicationContext类中一些重要信息
//创建上下文的唯一标识
private String id = ObjectUtils.identityToString(this);
//显示的名字
private String displayName = ObjectUtils.identityToString(this);
ObjectUtils工具类部分方法
//可得到(obj的全类名+'@'+obj的hashCode的十六进制字符串),如果obj为null,返回空字符串
private static final String EMPTY_STRING = "";
public static String identityToString(@Nullable Object obj) {
// 如果对象为null
if (obj == null) {
// 返回空字符串
return EMPTY_STRING;
}
// 拼接obj的全类名+'@'+obj的hashCode的十六进制字符串,然后返回出去
String className = obj.getClass().getName();
String identityHexString = getIdentityHexString(obj);
return className + '@' + identityHexString;
}
//用来存放beanFactory的后置处理器集合
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
//容器激活标志
private final AtomicBoolean active = new AtomicBoolean();
//容器关闭标志
private final AtomicBoolean closed = new AtomicBoolean();
//刷新和销毁的同步监视器
private final Object startupShutdownMonitor = new Object();
//创建一个无父类的AbstractApplicationContext对象
public AbstractApplicationContext() {
// 创建资源模式处理器
this.resourcePatternResolver = getResourcePatternResolver();
}
protected ResourcePatternResolver getResourcePatternResolver() {
// 创建一个资源模式解析器(用来解析xml配置文件)
return new PathMatchingResourcePatternResolver(this);
}
PathMatchingResourcePatternResolver类中一些重要信息
private final ResourceLoader resourceLoader;
// 创建ant方式的路径匹配器 - 目前几乎不用
private PathMatcher pathMatcher = new AntPathMatcher();
//new PathMatchingResourcePatternResolver
public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
this.resourceLoader = resourceLoader;
}
setParent(parent)
//设置此应用程序上下文的父级。parent参数为null
@Override
public void setParent(@Nullable ApplicationContext parent) {
this.parent = parent;
//如果父容器不为空
if (parent != null) {
//获取父容器的环境对象
Environment parentEnvironment = parent.getEnvironment();
//如果父容器的环境对象是一个可配置的环境对象
if (parentEnvironment instanceof ConfigurableEnvironment) {
getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
}
}
}
AbstractXmlApplicationContext类
ClassPathXmlApplicationContext继承AbstractXmlApplicationContext抽象类
注意:在new子类对象时,会开辟一块内存空间,同时调用父类构造方法(并不会new一个父类对象),再把父类中的成员变量和方法也加载到这块内存空间;至于super调用,是访问了这个空间特定部分的数据(也就是专门存储父类数据的内存部分)。
AbstractXmlApplicationContext类中一些重要信息
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {}
// 设置xml文件的验证标志,默认是true
private boolean validating = true;
二、setConfigLocations(configLocations)
//设置应用程序上下文的配置路径,如果未设置,则实现可以根据需要使用默认值。
//此处参数locations是一个空数组
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++) {
// 解析给定路径
this.configLocations[i] = resolvePath(locations[i]).trim();
}
}
else {
this.configLocations = null;
}
}