Spring启动流程(基于xml)
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
// 父类构造方法,最终实例化ResourcePatternResolver
super(parent);
/*
* 1.实例环境属性
* 2.设置配置文件路径(替换占位符)
*/
setConfigLocations(configLocations);
// refresh
if (refresh) {
refresh();
}
}
1.构造ClassPathXmlApplicationContext
构造顺序
ClassPathXmlApplicationContext
-> super(AbstractXmlApplicationContext)
-> super(AbstractRefreshableConfigApplicationContext)
-> super(AbstractRefreshableApplicationContext)
-> super(AbstractApplicationContext)
// 最后实例ResourcePatternResolver
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
this();
setParent(parent);
}
this():
public AbstractApplicationContext() {
// 设置resourcePatternResolver
this.resourcePatternResolver = getResourcePatternResolver();
}
getResourcePatternResolver():
protected ResourcePatternResolver getResourcePatternResolver() {
return new PathMatchingResourcePatternResolver(this);
}
PathMatchingResourcePatternResolver(this):
public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
// 设置resourceLoader
this.resourceLoader = resourceLoader;
}
2.setConfigLocations(configLocations)
// 设置configLocations
public void setConfigLocations(@Nullable String... locations) {
// locations : 配置文件名称数组 例["applicationContext.xml",...]
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;
}
}
resolvePath(locations[i]).trim():
protected String resolvePath(String path) {
return getEnvironment().resolveRequiredPlaceholders(path);
}
1.初始化环境变量
// 初始化环境变量 => 最终实例AbstractEnvironment
getEnvironment:
public ConfigurableEnvironment getEnvironment() {
if (this.environment == null) {
this.environment = createEnvironment();
}
return this.environment;
}
createEnvironment:
protected ConfigurableEnvironment createEnvironment() {
return new StandardEnvironment();
}
public StandardEnvironment() {
}
AbstractEnvironment():
2.解析占位符
resolveRequiredPlaceholders(path):
public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
return this.propertyResolver.resolveRequiredPlaceholders(text);
}
resolveRequiredPlaceholders(text):
public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
// 创建strictHelper
if (this.strictHelper == null) {
this.strictHelper = createPlaceholderHelper(false);
}
// 替换占位符
return doResolvePlaceholders(text, this.strictHelper);
}
1.创建占位符解析工具
createPlaceholderHelper(false):
private PropertyPlaceholderHelper createPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {
// this.placeholderPrefix = "${"
// this.placeholderSuffix = "}"
// this.valueSeparator = ":"
// this.ignoreUnresolvablePlaceholders = false
return new PropertyPlaceholderHelper(this.placeholderPrefix, this.placeholderSuffix,
this.valueSeparator, ignoreUnresolvablePlaceholders);
}
public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix,
@Nullable String valueSeparator, boolean ignoreUnresolvablePlaceholders) {
Assert.notNull(placeholderPrefix, "'placeholderPrefix' must not be null");
Assert.notNull(placeholderSuffix, "'placeholderSuffix' must not be null");
// 设置开始符
this.placeholderPrefix = placeholderPrefix;
// 设置结束符
this.placeholderSuffix = placeholderSuffix;
// 设置配对符
String simplePrefixForSuffix = wellKnownSimplePrefixes.get(this.placeholderSuffix);
if (simplePrefixForSuffix != null && this.placeholderPrefix.endsWith(simplePrefixForSuffix)) {
this.simplePrefix = simplePrefixForSuffix;
}
else {
this.simplePrefix = this.placeholderPrefix;
}
// 设置分隔符
this.valueSeparator = valueSeparator;
// 设置是否忽略不可解析标志
this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
}
2.解析
doResolvePlaceholders:
private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {
return helper.replacePlaceholders(text, this::getPropertyAsRawString);
}
- 获取属性
- propertySource.getProperty,不同propertySource执行器获取property值
- 判断是否需要占位符解析
- 转化value
- 判断是否需要转化
- 根据source,target类型获取转化执行器GenericConverter
- 转化
```java
this::getPropertyAsRawString:
protected String getPropertyAsRawString(String key) {
return getProperty(key, String.class, false);
}
protected
T getProperty(String key, Class targetValueType, boolean resolveNestedPlaceholders) { if (this.propertySources != null) { for (PropertySource<?> propertySource : this.propertySources) { // isTraceEnable => 记录日志 if (logger.isTraceEnabled()) {
} // 获取value : 策略模式 Object value = propertySource.getProperty(key); if (value != null) {logger.trace("Searching for key '" + key + "' in PropertySource '" +
propertySource.getName() + "'");
} } } if (logger.isTraceEnabled()) { logger.trace(“Could not find key ‘“ + key + “‘ in any property source”); } return null; }if (resolveNestedPlaceholders && value instanceof String) {
// value是否需要占位符解析 => resolveRequiredPlaceholders(...) 是:创建普通占位符解析工具 否:nonStrictHelper = null
value = resolveNestedPlaceholders((String) value);
}
// 记录key被找到
logKeyFound(key, propertySource, value);
// 转化value
return convertValueIfNecessary(value, targetValueType);
convertValueIfNecessary:
protected
isAssignableValue: public static boolean isAssignableValue(Class<?> type, @Nullable Object value) { Assert.notNull(type, “Type must not be null”); // 1.如果value不为空 = > isAssignable // 2.为空 => 是否 不是基本数据类型 return (value != null ? isAssignable(type, value.getClass()) : !type.isPrimitive()); }
isAssignable: public static boolean isAssignable(Class<?> lhsType, Class<?> rhsType) { Assert.notNull(lhsType, “Left-hand side type must not be null”); Assert.notNull(rhsType, “Right-hand side type must not be null”); // 存在继承关系或相同类,lhsType父类,rhsType子类 if (lhsType.isAssignableFrom(rhsType)) { return true; } // 基础数据类型 if (lhsType.isPrimitive()) { Class<?> resolvedPrimitive = primitiveWrapperTypeMap.get(rhsType); return (lhsType == resolvedPrimitive); } else { // 基本数据类型和对应数组 + void.class Class<?> resolvedWrapper = primitiveTypeToWrapperMap.get(rhsType); return (resolvedWrapper != null && lhsType.isAssignableFrom(resolvedWrapper)); } }
convert:
public
* desc不为空返回,为空new TypeDescriptor(new ResolvableType(clazz),null,null)
* this.type = resolvableType.toClass
*/
return (desc != null ? desc : new TypeDescriptor(ResolvableType.forClass(type), null, null));
}
public Object convert(@Nullable Object source, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType) { Assert.notNull(targetType, “Target type to convert to cannot be null”); if (sourceType == null) { Assert.isTrue(source == null, “Source must be [null] if source type == [null]”); return handleResult(null, targetType, convertNullSource(null, targetType)); } if (source != null && !sourceType.getObjectType().isInstance(source)) { throw new IllegalArgumentException(“Source to convert from must be an instance of [“ + sourceType + “]; instead it was a [“ + source.getClass().getName() + “]”); } // 根据两种类型 => 获取GenericConverter GenericConverter converter = getConverter(sourceType, targetType); if (converter != null) { // invokeConverter 转化 : 代理模式 Object result = ConversionUtils.invokeConverter(converter, source, sourceType, targetType); return handleResult(sourceType, targetType, result); } // 没找到GenericConverter return handleConverterNotFound(source, sourceType, targetType); }
2. 占位符解析
```java
protected String parseStringValue(
String value, PlaceholderResolver placeholderResolver, @Nullable Set<String> visitedPlaceholders) {
// 开始下标
int startIndex = value.indexOf(this.placeholderPrefix);
if (startIndex == -1) {
return value;
}
// 结果StringBuilder
StringBuilder result = new StringBuilder(value);
while (startIndex != -1) {
// 寻找结束下标
int endIndex = findPlaceholderEndIndex(result, startIndex);
if (endIndex != -1) {
// 截取开始~结束部分 = placeholder
String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);
String originalPlaceholder = placeholder;
if (visitedPlaceholders == null) {
visitedPlaceholders = new HashSet<>(4);
}
// placeholder放入visitedPlaceholders,如果已经存在产生循环遍历
if (!visitedPlaceholders.add(originalPlaceholder)) {
throw new IllegalArgumentException(
"Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
}
// 递归执行开始~结束部分,例:${${}}嵌套占位符情况
placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
// 函数式接口 :: getPropertyAsRawString,获取属性
String propVal = placeholderResolver.resolvePlaceholder(placeholder);
// 获取解析属性 = null,解析分隔符前文本
if (propVal == null && this.valueSeparator != null) {
// 根据valueSeparator截取
int separatorIndex = placeholder.indexOf(this.valueSeparator);
if (separatorIndex != -1) {
// : 前
String actualPlaceholder = placeholder.substring(0, separatorIndex);
// : 后 默认值
String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
// 解析 :前的值 - null情况取默认值
propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
if (propVal == null) {
propVal = defaultValue;
}
}
}
if (propVal != null) {
// 递归解析
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) {
// 重置开始下标
startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
}
else {
throw new IllegalArgumentException("Could not resolve placeholder '" +
placeholder + "'" + " in value \"" + value + "\"");
}
// 移除originalPlaceholder
visitedPlaceholders.remove(originalPlaceholder);
}
else {
// 找不到结束下标
startIndex = -1;
}
}
// 返回结果
return result.toString();
}
3.prepareRefresh
protected void prepareRefresh() {
// 启动时间
this.startupDate = System.currentTimeMillis();
// 关闭状态
this.closed.set(false);
// 活跃状态
this.active.set(true);
// log
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
} else {
logger.debug("Refreshing " + getDisplayName());
}
}
// 扩展PropertySources
initPropertySources();
// 验证requiredProperties是否都存在
getEnvironment().validateRequiredProperties();
// 实例化earlyApplication
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
// 重置applicationListeners,[add]earlyApplicationListeners
} else {
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// 清空earlyApplicationEvents
this.earlyApplicationEvents = new LinkedHashSet<>();
}
拓展initPropertySources重写即可
protected void initPropertySources() {
// For subclasses: do nothing by default.
}
validateRequiredProperties:
@Override
public void validateRequiredProperties() {
MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
for (String key : this.requiredProperties) {
// 获取属性不为空add
if (this.getProperty(key) == null) {
ex.addMissingRequiredProperty(key);
}
}
// ex有数据,抛出异常
if (!ex.getMissingRequiredProperties().isEmpty()) {
throw ex;
}
}
4.obtainFreshBeanFactory()
public final ConfigurableListableBeanFactory getBeanFactory() {
DefaultListableBeanFactory beanFactory = this.beanFactory;
if (beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return beanFactory;
}
1.加载xml
2.解析xmlx
3.封装BeanDefinition
4.实例化
BeanDefinition -> 反射实例化
动态更改Bean信息 -> BeanFactoryPostProcessor -> … -> …
PostProcessor(后置处理器) -> 1.BeanFactoryPostProcessor -> 增强BeanDefinition信息
-> 2.BeanPostProcessor -> 增强Bean信息
实例化 -> 填充属性 -> 设置Aware接口属性(当创建Bean对象时候需要其他容器对象,实现Aware满足) -> 初始化 -> BeanPostProcessor.before -> initMethod -> BeanPostProcessor.after -> 完整对象
BeanFactory 和 FactoryBean
if(FactoryBean exist) => FactoryBean.create
else => 走BeanFactory流程实现
5.放入容器 - Map(三级缓存)
6.从容器中获取