spring 源码解读一 ClassPathXmlApplicationContext

 

最近闲来无事翻阅了下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的最核心的方法了,下一章进行解读

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值