开始进入spring

  1. ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
  2. application.xml文件
  3. <?xml version="1.0" encoding="UTF-8"?>
  4. <beans xmlns="http://www.springframework.org/schema/beans"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xmlns:context="http://www.springframework.org/schema/context"
  7. 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">
  8. <context:component-scan base-package="com.mashibing"></context:component-scan>
  9. <bean id="person" class="com.mashibing.Person">
  10. <constructor-arg name="id" value="1"></constructor-arg>
  11. <constructor-arg name="name" value="lisi"></constructor-arg>
  12. </bean>
  13. </beans>

通过new ClassPathXmlApplicationContext会调用构造方法

  1. public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {}
  2. /**
  3. * 创建一个新的ClassPathXmlApplicationContext,从xml文件中加载给定的bean定义信息,并且刷新上下文
  4. */
  5. public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
  6. //调用下面的构造方法,此处3个参数
  7. this(new String[] {configLocation}, true, null);
  8. }
  9. //传递过来的configLocations空数组,refresh为true,parent为null
  10. public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh,
  11. @Nullable ApplicationContext parent)
  12. throws BeansException {
  13. // 一、调用父类构造方法,进行相关的对象创建等操作,包含属性的赋值操作
  14. super(parent);
  15. // 二、
  16. setConfigLocations(configLocations);
  17. if (refresh) {
  18. refresh();
  19. }
  20. }

一、super(parent)父类构造方法

  1. //parent参数为null
  2. public AbstractApplicationContext(@Nullable ApplicationContext parent) {
  3. //调用本类无参构造
  4. this();
  5. setParent(parent);
  6. }

this():AbstractApplicationContext类

  1. AbstractApplicationContext类中一些重要信息
  2. //创建上下文的唯一标识
  3. private String id = ObjectUtils.identityToString(this);
  4. //显示的名字
  5. private String displayName = ObjectUtils.identityToString(this);
  6. ObjectUtils工具类部分方法
  7. //可得到(obj的全类名+'@'+obj的hashCode的十六进制字符串),如果obj为null,返回空字符串
  8. private static final String EMPTY_STRING = "";
  9. public static String identityToString(@Nullable Object obj) {
  10. // 如果对象为null
  11. if (obj == null) {
  12. // 返回空字符串
  13. return EMPTY_STRING;
  14. }
  15. // 拼接obj的全类名+'@'+obj的hashCode的十六进制字符串,然后返回出去
  16. String className = obj.getClass().getName();
  17. String identityHexString = getIdentityHexString(obj);
  18. return className + '@' + identityHexString;
  19. }
  20. //用来存放beanFactory的后置处理器集合
  21. private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
  22. //容器激活标志
  23. private final AtomicBoolean active = new AtomicBoolean();
  24. //容器关闭标志
  25. private final AtomicBoolean closed = new AtomicBoolean();
  26. //刷新和销毁的同步监视器
  27. private final Object startupShutdownMonitor = new Object();
  28. //创建一个无父类的AbstractApplicationContext对象
  29. public AbstractApplicationContext() {
  30. // 创建资源模式处理器
  31. this.resourcePatternResolver = getResourcePatternResolver();
  32. }
  33. protected ResourcePatternResolver getResourcePatternResolver() {
  34. // 创建一个资源模式解析器(用来解析xml配置文件)
  35. return new PathMatchingResourcePatternResolver(this);
  36. }
  37. PathMatchingResourcePatternResolver类中一些重要信息
  38. private final ResourceLoader resourceLoader;
  39. // 创建ant方式的路径匹配器 - 目前几乎不用
  40. private PathMatcher pathMatcher = new AntPathMatcher();
  41. //new PathMatchingResourcePatternResolver
  42. public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
  43. Assert.notNull(resourceLoader, "ResourceLoader must not be null");
  44. this.resourceLoader = resourceLoader;
  45. }

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;
    }
}