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
