Spring源码解析(一)

Spring源码解析(一)spring 源码解析 spring 源码的真香定理开课了 ClassPathXml parent setConfigLoc configLocati

ClassPathXmlApplicationContext applicationContext =new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); applicationContext.getBean(""); 

进入ClassPathXmlApplicationContext 有参构造

public ClassPathXmlApplicationContext(String configLocation) throws BeansException { 
    this(new String[] { 
   configLocation}, true, null); } // 进入this(new String[] {configLocation}, true, null)方法 public ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { 
    //1.初始化父类,设置PathMatchingResourcePatternResolver(资源查找器,主要是获取资源文件的时候可以解析*,?等符号的路径) super(parent); //2.设置本地的配置信息 setConfigLocations(configLocations); //3.spring容器的初始化 if (refresh) { 
    refresh(); } } 

真正调用的就是ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent),它做了三件大事。

1.初始化父类

//这里是初始化AbstractXmlApplicationContext public AbstractXmlApplicationContext(@Nullable ApplicationContext parent) { 
    super(parent); } //继续跟踪super(parent); //初始化AbstractRefreshableConfigApplicationContext public AbstractRefreshableConfigApplicationContext(@Nullable ApplicationContext parent) { 
    super(parent); } //继续跟踪super(parent); //初始化AbstractRefreshableApplicationContext public AbstractRefreshableApplicationContext(@Nullable ApplicationContext parent) { 
    super(parent); } //继续跟踪super(parent); //初始化AbstractApplicationContext public AbstractApplicationContext(@Nullable ApplicationContext parent) { 
    //定义了一个资源查找器 this(); //ClassPathXmlApplicationContext 中的有参构造parent为null,所以这里啥也没干 setParent(parent); } 
//跟踪this() public AbstractApplicationContext() { 
    //为内部一个获取资源的属性赋值 this.resourcePatternResolver = getResourcePatternResolver(); } //getResourcePatternResolver() protected ResourcePatternResolver getResourcePatternResolver() { 
    //PathMatchingResourcePatternResolver这里就是真正的资源查找器,获取资源getResource方法就是用他的 return new PathMatchingResourcePatternResolver(this); } 
//就是判断了下parent是不是空,是空就啥也没干 public void setParent(@Nullable ApplicationContext parent) { 
    this.parent = parent; if (parent != null) { 
    Environment parentEnvironment = parent.getEnvironment(); if (parentEnvironment instanceof ConfigurableEnvironment) { 
    getEnvironment().merge((ConfigurableEnvironment) parentEnvironment); } } } 

补充说明,这里父类定义大量的模板,让子类实现,父类层层传递到子类 知道某个子类重载了抽象方法。这里应用到了职责链设计模式和模板设计模式。

2.设置本地的配置信息

跟踪源码setConfigLocations(configLocations);

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++) { 
    //循环取出每一个path参数,在此处就一个"applicationContext.xml" this.configLocations[i] = resolvePath(locations[i]).trim(); } } else { 
    this.configLocations = null; } } //跟踪resolvePath(locations[i]) protected String resolvePath(String path) { 
    //两部分,getEnvironment()创建环境对象StandardEnvironment,resolveRequiredPlaceholders(path)就是替换${}这样的值,就像你xml中引入另外一个文件,然后你会用${}一样,不过这里是从环境变量中去替换占位符 return getEnvironment().resolveRequiredPlaceholders(path); } //跟踪getEnvironment() public ConfigurableEnvironment getEnvironment() { 
    if (this.environment == null) { 
    this.environment = createEnvironment(); } return this.environment; } //继续跟踪createEnvironment() //实例化一个StandardEnvironment protected ConfigurableEnvironment createEnvironment() { 
    return new StandardEnvironment(); } 
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"; @Override protected void customizePropertySources(MutablePropertySources propertySources) { 
    propertySources.addLast(new MapPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties())); propertySources.addLast(new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment())); } } 

没有那就证明无参构造用的是父类AbstractEnvironment的,那来看看父类AbstractEnvironment的无参构造

private final MutablePropertySources propertySources = new MutablePropertySources(this.logger); public AbstractEnvironment() { 
    customizePropertySources(this.propertySources); if (logger.isDebugEnabled()) { 
    logger.debug("Initialized " + getClass().getSimpleName() + " with PropertySources " + this.propertySources); } } 
private final List<PropertySource<?>> propertySourceList = new CopyOnWriteArrayList<PropertySource<?>>(); 

很抽象是不是,没关系,用一个结构解释。

 Map<String,Object> map1=new HashMap<>(); map1.put("systemProperties","我是Java进程变量"); Map<String,Object> map2=new HashMap<>(); map2.put("systemEnvironment","我是系统环境变量"); PropertySource source1=new MapPropertySource("person",map1); PropertySource source2=new MapPropertySource("person",map2); List<PropertySource> list =new ArrayList<PropertySource>(); list.add(source1); list.add(source2); 

上图这个List list就相当于MutablePropertySources,相当于但是不等于,只是模拟让你稍微理解一下。

customizePropertySources(this.propertySources)方法AbstractEnvironment是空实现,啥也没有,所以这样是调用的StandardEnvironment的,也就是上面StandardEnvironment 唯一的一个方法

@Override protected void customizePropertySources(MutablePropertySources propertySources) { 
    propertySources.addLast(new MapPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties())); propertySources.addLast(new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment())); } 
@Override @SuppressWarnings({ 
   "unchecked", "rawtypes"}) public Map<String, Object> getSystemProperties() { 
    try { 
    return (Map) System.getProperties(); } catch (AccessControlException ex) { 
    return (Map) new ReadOnlySystemAttributesMap() { 
    @Override @Nullable protected String getSystemAttribute(String attributeName) { 
    try { 
    return System.getProperty(attributeName); } catch (AccessControlException ex) { 
    if (logger.isInfoEnabled()) { 
    logger.info("Caught AccessControlException when accessing system property '" + attributeName + "'; its value will be returned [null]. Reason: " + ex.getMessage()); } return null; } } }; } } @Override @SuppressWarnings({ 
   "unchecked", "rawtypes"}) public Map<String, Object> getSystemEnvironment() { 
    if (suppressGetenvAccess()) { 
    return Collections.emptyMap(); } try { 
    return (Map) System.getenv(); } catch (AccessControlException ex) { 
    return (Map) new ReadOnlySystemAttributesMap() { 
    @Override @Nullable protected String getSystemAttribute(String attributeName) { 
    try { 
    return System.getenv(attributeName); } catch (AccessControlException ex) { 
    if (logger.isInfoEnabled()) { 
    logger.info("Caught AccessControlException when accessing system environment variable '" + attributeName + "'; its value will be returned [null]. Reason: " + ex.getMessage()); } return null; } } }; } } 

系统环境搞定了,接下来是处理占位符了,跟踪一下resolveRequiredPlaceholders(path)

 public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException { 
    return this.propertyResolver.resolveRequiredPlaceholders(text); } //this.propertyResolver private final ConfigurablePropertyResolver propertyResolver = new PropertySourcesPropertyResolver(this.propertySources); //new PropertySourcesPropertyResolver(this.propertySources)就是设置了下环境变量的propertySources public PropertySourcesPropertyResolver(@Nullable PropertySources propertySources) { 
    this.propertySources = propertySources; } 
 Map<String,Object> map1=new HashMap<>(); map1.put("name","zhangsan"); PropertySource source=new MapPropertySource("person",map1); MutablePropertySources sources = new MutablePropertySources(); sources.addLast(source); PropertyResolver resolver = new PropertySourcesPropertyResolver(sources); System.out.println(resolver.containsProperty("name"));//输出 zhangsan System.out.println(resolver.resolvePlaceholders("My name is ${name} "));//输出My name is zhangsan 

接下来看resolveRequiredPlaceholders(text)方法,因为PropertySourcesPropertyResolver没有实现这个方法,所以在父类AbstractPropertyResolver中找到了

@Override public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException { 
    if (this.strictHelper == null) { 
    this.strictHelper = createPlaceholderHelper(false); } return doResolvePlaceholders(text, this.strictHelper); } //this.strictHelper private PropertyPlaceholderHelper strictHelper; //createPlaceholderHelper(false)定义一个PropertyPlaceholderHelper,并传参数用于判断是否忽略不能解析的变量 private PropertyPlaceholderHelper createPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) { 
    return new PropertyPlaceholderHelper(this.placeholderPrefix, this.placeholderSuffix, this.valueSeparator, ignoreUnresolvablePlaceholders); } //doResolvePlaceholders(text, this.strictHelper) private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) { 
    //找到字符串中的占位符,调用PropertyResolver.getPropertyAsRawString方法,从环境变量中取出占位符对应的值,用环境变量的值替换占位符 return helper.replacePlaceholders(text, this::getPropertyAsRawString); } 
//getPropertyAsRawString AbstractPropertyResolver空实现,所以看子类PropertySourcesPropertyResolver protected String getPropertyAsRawString(String key) { 
    return getProperty(key, String.class, false); } //getProperty(key, String.class, false) //找到占位符key对应的value @Nullable protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) { 
    if (this.propertySources != null) { 
    for (PropertySource<?> propertySource : this.propertySources) { 
    if (logger.isTraceEnabled()) { 
    logger.trace("Searching for key '" + key + "' in PropertySource '" + propertySource.getName() + "'"); } Object value = propertySource.getProperty(key); if (value != null) { 
    if (resolveNestedPlaceholders && value instanceof String) { 
    value = resolveNestedPlaceholders((String) value); } logKeyFound(key, propertySource, value); return convertValueIfNecessary(value, targetValueType); } } } if (logger.isDebugEnabled()) { 
    logger.debug("Could not find key '" + key + "' in any property source"); } return null; } 

replacePlaceholders方法就是替换:

 public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) { 
    Assert.notNull(value, "'value' must not be null"); return parseStringValue(value, placeholderResolver, new HashSet<>()); } //parseStringValue(value, placeholderResolver, new HashSet<>()) protected String parseStringValue( String value, PlaceholderResolver placeholderResolver, Set<String> visitedPlaceholders) { 
    StringBuilder result = new StringBuilder(value); int startIndex = value.indexOf(this.placeholderPrefix); while (startIndex != -1) { 
    int endIndex = findPlaceholderEndIndex(result, startIndex); if (endIndex != -1) { 
    String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex); String originalPlaceholder = placeholder; if (!visitedPlaceholders.add(originalPlaceholder)) { 
    throw new IllegalArgumentException( "Circular placeholder reference '" + originalPlaceholder + "' in property definitions"); } //这里有迭代操作,确保处理完字符串中所有的占位符 placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders); // 这里实际上会调用PropertySourcesPropertyResolver.getPropertyAsRawString方法,propVal的值就是从环境变量中取得的值 String propVal = placeholderResolver.resolvePlaceholder(placeholder); if (propVal == null && this.valueSeparator != null) { 
    int separatorIndex = placeholder.indexOf(this.valueSeparator); if (separatorIndex != -1) { 
    String actualPlaceholder = placeholder.substring(0, separatorIndex); String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length()); propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder); if (propVal == null) { 
    propVal = defaultValue; } } } if (propVal != null) { 
    // Recursive invocation, parsing placeholders contained in the // previously resolved placeholder value. propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders); result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal); if (logger.isTraceEnabled()) { 
    logger.trace("Resolved placeholder '" + placeholder + "'"); } startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length()); } else if (this.ignoreUnresolvablePlaceholders) { 
    // Proceed with unprocessed value. startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length()); } else { 
    throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "'" + " in value \"" + value + "\""); } visitedPlaceholders.remove(originalPlaceholder); } else { 
    startIndex = -1; } } return result.toString(); } 
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/229293.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午5:02
下一篇 2026年3月16日 下午5:02


相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号