Spring启动流程(基于xml)

  1. public ClassPathXmlApplicationContext(
  2. String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
  3. throws BeansException {
  4. // 父类构造方法,最终实例化ResourcePatternResolver
  5. super(parent);
  6. /*
  7. * 1.实例环境属性
  8. * 2.设置配置文件路径(替换占位符)
  9. */
  10. setConfigLocations(configLocations);
  11. // refresh
  12. if (refresh) {
  13. refresh();
  14. }
  15. }

1.构造ClassPathXmlApplicationContext

image.png
构造顺序
ClassPathXmlApplicationContext
-> super(AbstractXmlApplicationContext)
-> super(AbstractRefreshableConfigApplicationContext)
-> super(AbstractRefreshableApplicationContext)
-> super(AbstractApplicationContext)

  1. // 最后实例ResourcePatternResolver
  2. public AbstractApplicationContext(@Nullable ApplicationContext parent) {
  3. this();
  4. setParent(parent);
  5. }
  6. this():
  7. public AbstractApplicationContext() {
  8. // 设置resourcePatternResolver
  9. this.resourcePatternResolver = getResourcePatternResolver();
  10. }
  11. getResourcePatternResolver():
  12. protected ResourcePatternResolver getResourcePatternResolver() {
  13. return new PathMatchingResourcePatternResolver(this);
  14. }
  15. PathMatchingResourcePatternResolver(this):
  16. public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
  17. Assert.notNull(resourceLoader, "ResourceLoader must not be null");
  18. // 设置resourceLoader
  19. this.resourceLoader = resourceLoader;
  20. }

2.setConfigLocations(configLocations)

  1. // 设置configLocations
  2. public void setConfigLocations(@Nullable String... locations) {
  3. // locations : 配置文件名称数组 例["applicationContext.xml",...]
  4. if (locations != null) {
  5. Assert.noNullElements(locations, "Config locations must not be null");
  6. this.configLocations = new String[locations.length];
  7. for (int i = 0; i < locations.length; i++) {
  8. // 遍历解析
  9. this.configLocations[i] = resolvePath(locations[i]).trim();
  10. }
  11. } else {
  12. this.configLocations = null;
  13. }
  14. }
  15. resolvePath(locations[i]).trim():
  16. protected String resolvePath(String path) {
  17. return getEnvironment().resolveRequiredPlaceholders(path);
  18. }

1.初始化环境变量

image.png

  1. // 初始化环境变量 => 最终实例AbstractEnvironment
  2. getEnvironment:
  3. public ConfigurableEnvironment getEnvironment() {
  4. if (this.environment == null) {
  5. this.environment = createEnvironment();
  6. }
  7. return this.environment;
  8. }
  9. createEnvironment:
  10. protected ConfigurableEnvironment createEnvironment() {
  11. return new StandardEnvironment();
  12. }
  13. public StandardEnvironment() {
  14. }
  15. AbstractEnvironment():

2.解析占位符

  1. resolveRequiredPlaceholders(path):
  2. public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
  3. return this.propertyResolver.resolveRequiredPlaceholders(text);
  4. }
  5. resolveRequiredPlaceholders(text):
  6. public String resolveRequiredPlaceholders(String text) throws IllegalArgumentException {
  7. // 创建strictHelper
  8. if (this.strictHelper == null) {
  9. this.strictHelper = createPlaceholderHelper(false);
  10. }
  11. // 替换占位符
  12. return doResolvePlaceholders(text, this.strictHelper);
  13. }

1.创建占位符解析工具

  1. createPlaceholderHelper(false):
  2. private PropertyPlaceholderHelper createPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {
  3. // this.placeholderPrefix = "${"
  4. // this.placeholderSuffix = "}"
  5. // this.valueSeparator = ":"
  6. // this.ignoreUnresolvablePlaceholders = false
  7. return new PropertyPlaceholderHelper(this.placeholderPrefix, this.placeholderSuffix,
  8. this.valueSeparator, ignoreUnresolvablePlaceholders);
  9. }
  10. public PropertyPlaceholderHelper(String placeholderPrefix, String placeholderSuffix,
  11. @Nullable String valueSeparator, boolean ignoreUnresolvablePlaceholders) {
  12. Assert.notNull(placeholderPrefix, "'placeholderPrefix' must not be null");
  13. Assert.notNull(placeholderSuffix, "'placeholderSuffix' must not be null");
  14. // 设置开始符
  15. this.placeholderPrefix = placeholderPrefix;
  16. // 设置结束符
  17. this.placeholderSuffix = placeholderSuffix;
  18. // 设置配对符
  19. String simplePrefixForSuffix = wellKnownSimplePrefixes.get(this.placeholderSuffix);
  20. if (simplePrefixForSuffix != null && this.placeholderPrefix.endsWith(simplePrefixForSuffix)) {
  21. this.simplePrefix = simplePrefixForSuffix;
  22. }
  23. else {
  24. this.simplePrefix = this.placeholderPrefix;
  25. }
  26. // 设置分隔符
  27. this.valueSeparator = valueSeparator;
  28. // 设置是否忽略不可解析标志
  29. this.ignoreUnresolvablePlaceholders = ignoreUnresolvablePlaceholders;
  30. }

2.解析

  1. doResolvePlaceholders:
  2. private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {
  3. return helper.replacePlaceholders(text, this::getPropertyAsRawString);
  4. }
  1. 获取属性
    1. propertySource.getProperty,不同propertySource执行器获取property值
    2. 判断是否需要占位符解析
    3. 转化value
      1. 判断是否需要转化
      2. 根据source,target类型获取转化执行器GenericConverter
      3. 转化 ```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()) {
        1. logger.trace("Searching for key '" + key + "' in PropertySource '" +
        2. propertySource.getName() + "'");
        } // 获取value : 策略模式 Object value = propertySource.getProperty(key); if (value != null) {
        1. if (resolveNestedPlaceholders && value instanceof String) {
        2. // value是否需要占位符解析 => resolveRequiredPlaceholders(...) 是:创建普通占位符解析工具 否:nonStrictHelper = null
        3. value = resolveNestedPlaceholders((String) value);
        4. }
        5. // 记录key被找到
        6. logKeyFound(key, propertySource, value);
        7. // 转化value
        8. return convertValueIfNecessary(value, targetValueType);
        } } } if (logger.isTraceEnabled()) { logger.trace(“Could not find key ‘“ + key + “‘ in any property source”); } return null; }

convertValueIfNecessary: protected T convertValueIfNecessary(Object value, @Nullable Class targetType) { if (targetType == null) { return (T) value; } ConversionService conversionServiceToUse = this.conversionService; if (conversionServiceToUse == null) { // 如果不必要不需要转化 if (ClassUtils.isAssignableValue(targetType, value)) { return (T) value; } // 实例化conversionServiceToUse conversionServiceToUse = DefaultConversionService.getSharedInstance(); } // 转化 return conversionServiceToUse.convert(value, targetType); }

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 T convert:(@Nullable Object source, Class targetType) { Assert.notNull(targetType, “Target type to convert to cannot be null”); return (T) convert(source, TypeDescriptor.forObject(source), TypeDescriptor.valueOf(targetType)); } public static TypeDescriptor forObject(@Nullable Object source) { return (source != null ? valueOf(source.getClass()) : null); } public static TypeDescriptor valueOf(@Nullable Class<?> type) { if (type == null) { type = Object.class; } TypeDescriptor desc = commonTypesCache.get(type); /*

  1. * desc不为空返回,为空new TypeDescriptor(new ResolvableType(clazz),null,null)
  2. * this.type = resolvableType.toClass
  3. */
  4. 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); }

  1. 2. 占位符解析
  2. ```java
  3. protected String parseStringValue(
  4. String value, PlaceholderResolver placeholderResolver, @Nullable Set<String> visitedPlaceholders) {
  5. // 开始下标
  6. int startIndex = value.indexOf(this.placeholderPrefix);
  7. if (startIndex == -1) {
  8. return value;
  9. }
  10. // 结果StringBuilder
  11. StringBuilder result = new StringBuilder(value);
  12. while (startIndex != -1) {
  13. // 寻找结束下标
  14. int endIndex = findPlaceholderEndIndex(result, startIndex);
  15. if (endIndex != -1) {
  16. // 截取开始~结束部分 = placeholder
  17. String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);
  18. String originalPlaceholder = placeholder;
  19. if (visitedPlaceholders == null) {
  20. visitedPlaceholders = new HashSet<>(4);
  21. }
  22. // placeholder放入visitedPlaceholders,如果已经存在产生循环遍历
  23. if (!visitedPlaceholders.add(originalPlaceholder)) {
  24. throw new IllegalArgumentException(
  25. "Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
  26. }
  27. // 递归执行开始~结束部分,例:${${}}嵌套占位符情况
  28. placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
  29. // 函数式接口 :: getPropertyAsRawString,获取属性
  30. String propVal = placeholderResolver.resolvePlaceholder(placeholder);
  31. // 获取解析属性 = null,解析分隔符前文本
  32. if (propVal == null && this.valueSeparator != null) {
  33. // 根据valueSeparator截取
  34. int separatorIndex = placeholder.indexOf(this.valueSeparator);
  35. if (separatorIndex != -1) {
  36. // : 前
  37. String actualPlaceholder = placeholder.substring(0, separatorIndex);
  38. // : 后 默认值
  39. String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
  40. // 解析 :前的值 - null情况取默认值
  41. propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
  42. if (propVal == null) {
  43. propVal = defaultValue;
  44. }
  45. }
  46. }
  47. if (propVal != null) {
  48. // 递归解析
  49. propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
  50. result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
  51. if (logger.isTraceEnabled()) {
  52. logger.trace("Resolved placeholder '" + placeholder + "'");
  53. }
  54. // 重置开始下标
  55. startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());
  56. }
  57. else if (this.ignoreUnresolvablePlaceholders) {
  58. // 重置开始下标
  59. startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
  60. }
  61. else {
  62. throw new IllegalArgumentException("Could not resolve placeholder '" +
  63. placeholder + "'" + " in value \"" + value + "\"");
  64. }
  65. // 移除originalPlaceholder
  66. visitedPlaceholders.remove(originalPlaceholder);
  67. }
  68. else {
  69. // 找不到结束下标
  70. startIndex = -1;
  71. }
  72. }
  73. // 返回结果
  74. return result.toString();
  75. }

3.prepareRefresh

  1. protected void prepareRefresh() {
  2. // 启动时间
  3. this.startupDate = System.currentTimeMillis();
  4. // 关闭状态
  5. this.closed.set(false);
  6. // 活跃状态
  7. this.active.set(true);
  8. // log
  9. if (logger.isDebugEnabled()) {
  10. if (logger.isTraceEnabled()) {
  11. logger.trace("Refreshing " + this);
  12. } else {
  13. logger.debug("Refreshing " + getDisplayName());
  14. }
  15. }
  16. // 扩展PropertySources
  17. initPropertySources();
  18. // 验证requiredProperties是否都存在
  19. getEnvironment().validateRequiredProperties();
  20. // 实例化earlyApplication
  21. if (this.earlyApplicationListeners == null) {
  22. this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
  23. // 重置applicationListeners,[add]earlyApplicationListeners
  24. } else {
  25. this.applicationListeners.clear();
  26. this.applicationListeners.addAll(this.earlyApplicationListeners);
  27. }
  28. // 清空earlyApplicationEvents
  29. this.earlyApplicationEvents = new LinkedHashSet<>();
  30. }

拓展initPropertySources重写即可

  1. protected void initPropertySources() {
  2. // For subclasses: do nothing by default.
  3. }
  1. validateRequiredProperties:
  2. @Override
  3. public void validateRequiredProperties() {
  4. MissingRequiredPropertiesException ex = new MissingRequiredPropertiesException();
  5. for (String key : this.requiredProperties) {
  6. // 获取属性不为空add
  7. if (this.getProperty(key) == null) {
  8. ex.addMissingRequiredProperty(key);
  9. }
  10. }
  11. // ex有数据,抛出异常
  12. if (!ex.getMissingRequiredProperties().isEmpty()) {
  13. throw ex;
  14. }
  15. }

4.obtainFreshBeanFactory()

  1. public final ConfigurableListableBeanFactory getBeanFactory() {
  2. DefaultListableBeanFactory beanFactory = this.beanFactory;
  3. if (beanFactory == null) {
  4. throw new IllegalStateException("BeanFactory not initialized or already closed - " +
  5. "call 'refresh' before accessing beans via the ApplicationContext");
  6. }
  7. return beanFactory;
  8. }

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.从容器中获取