运行SpringApplication二

回顾之前的代码,主要做了两件事

  1. 将配置的运行监听器实例化
  2. 创建启动事件实例,并推送给适配的监听器处理(logback读取配置文件、完成预初始化)

继续

创建应用参数集合实例

ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);

— DefaultApplicationArguments start

org.springframework.boot.DefaultApplicationArguments

private final Source source;

private final String[] args;

public DefaultApplicationArguments(String... args) {
	Assert.notNull(args, "Args must not be null");
	this.source = new Source(args);
	this.args = args;
}

—— Source start

org.springframework.boot.ApplicationArguments$Source

Source(String[] args) {
	super(args);
}

查看父级构造方法

——— SimpleCommandLinePropertySource start

org.springframework.core.env.SimpleCommandLinePropertySource

public SimpleCommandLinePropertySource(String... args) {
	super(new SimpleCommandLineArgsParser().parse(args));
}

重点看解析方法

———— parse start

org.springframework.core.env.SimpleCommandLineArgsParser

public CommandLineArgs parse(String... args) {
	CommandLineArgs commandLineArgs = new CommandLineArgs();
	for (String arg : args) {
		if (arg.startsWith("--")) {
			String optionText = arg.substring(2);
			String optionName;
			String optionValue = null;
			int indexOfEqualsSign = optionText.indexOf('=');
			if (indexOfEqualsSign > -1) {
				optionName = optionText.substring(0, indexOfEqualsSign);
				optionValue = optionText.substring(indexOfEqualsSign + 1);
			}
			else {
				optionName = optionText;
			}
			if (optionName.isEmpty()) {
				throw new IllegalArgumentException("Invalid argument syntax: " + arg);
			}
				commandLineArgs.addOptionArg(optionName, optionValue);
		}
		else {
			commandLineArgs.addNonOptionArg(arg);
		}
	}
	return commandLineArgs;
}

遍历参数集合
若参数是否以 - - 开头,根据 = 拆分参数名与值,通过addOptionArg方法添加

commandLineArgs.addOptionArg(optionName, optionValue);

————— addOptionArg start

org.springframework.core.env.CommandLineArgs

private final Map<String, List<String>> optionArgs = new HashMap<>();

public void addOptionArg(String optionName, @Nullable String optionValue) {
	if (!this.optionArgs.containsKey(optionName)) {
		this.optionArgs.put(optionName, new ArrayList<>());
	}
	if (optionValue != null) {
		this.optionArgs.get(optionName).add(optionValue);
	}
}

————— addOptionArg end
否则通过addNonOptionArg方法添加

commandLineArgs.addNonOptionArg(arg);

————— addNonOptionArg start

org.springframework.core.env.CommandLineArgs

private final List<String> nonOptionArgs = new ArrayList<>();

public void addNonOptionArg(String value) {
	this.nonOptionArgs.add(value);
}

————— addNonOptionArg end
———— parse end

接着看父级构造方法

———— CommandLinePropertySource start

org.springframework.core.env.CommandLinePropertySource

public static final String COMMAND_LINE_PROPERTY_SOURCE_NAME = "commandLineArgs";

public CommandLinePropertySource(T source) {
	super(COMMAND_LINE_PROPERTY_SOURCE_NAME, source);
}
接着看父级构造方法

————— EnumerablePropertySource start

org.springframework.util.ObjectUtils.EnumerablePropertySource

public EnumerablePropertySource(String name, T source) {
	super(name, source);
}
接着看父级构造方法

—————— PropertySource start

org.springframework.core.env.PropertySource

protected final String name;

protected final T source;

public PropertySource(String name, T source) {
	Assert.hasText(name, "Property source name must contain at least one character");
	Assert.notNull(source, "Property source must not be null");
	this.name = name;
	this.source = source;
}

—————— PropertySource end
————— EnumerablePropertySource end
———— CommandLinePropertySource end
——— SimpleCommandLinePropertySource end
—— Source end
— DefaultApplicationArguments end

准备环境

ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);

— prepareEnvironment start

org.springframework.boot.SpringApplication

private ConfigurableEnvironment prepareEnvironment(SpringApplicationRunListeners listeners,
		DefaultBootstrapContext bootstrapContext, ApplicationArguments applicationArguments) {
	// Create and configure the environment
	ConfigurableEnvironment environment = getOrCreateEnvironment();
	configureEnvironment(environment, applicationArguments.getSourceArgs());
	ConfigurationPropertySources.attach(environment);
	listeners.environmentPrepared(bootstrapContext, environment);
	DefaultPropertiesPropertySource.moveToEnd(environment);
	Assert.state(!environment.containsProperty("spring.main.environment-prefix"),
			"Environment prefix cannot be set via properties.");
	bindToSpringApplication(environment);
	if (!this.isCustomEnvironment) {
		environment = convertEnvironment(environment);
	}
	ConfigurationPropertySources.attach(environment);
	return environment;
}

获取或创建环境实例

ConfigurableEnvironment environment = getOrCreateEnvironment();

—— getOrCreateEnvironment start

org.springframework.boot.SpringApplication

private ConfigurableEnvironment getOrCreateEnvironment() {
	if (this.environment != null) {
		return this.environment;
	}
	switch (this.webApplicationType) {
	case SERVLET:
		return new ApplicationServletEnvironment();
	case REACTIVE:
		return new ApplicationReactiveWebEnvironment();
	default:
		return new ApplicationEnvironment();
	}
}

由于此前未创建环境实例,environmentnull
根据webApplicationType创建并返回org.springframework.boot.ApplicationEnvironment实例

查看父类构造方法

——— AbstractEnvironment start

org.springframework.core.env.AbstractEnvironment

private final MutablePropertySources propertySources;

private final ConfigurablePropertyResolver propertyResolver;

public AbstractEnvironment() {
	this(new MutablePropertySources());
}

protected AbstractEnvironment(MutablePropertySources propertySources) {
	this.propertySources = propertySources;
	this.propertyResolver = createPropertyResolver(propertySources);
	customizePropertySources(propertySources);
}
创建属性分解器
this.propertyResolver = createPropertyResolver(propertySources);

———— createPropertyResolver start

org.springframework.boot.ApplicationEnvironment

@Override
protected ConfigurablePropertyResolver createPropertyResolver(MutablePropertySources propertySources) {
	return ConfigurationPropertySources.createPropertyResolver(propertySources);
}

————— createPropertyResolver start

org.springframework.boot.context.properties.source.ConfigurationPropertySources

public static ConfigurablePropertyResolver createPropertyResolver(MutablePropertySources propertySources) {
	return new ConfigurationPropertySourcesPropertyResolver(propertySources);
}
创建配置属性资源属性分解器

—————— ConfigurationPropertySourcesPropertyResolver start

org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver

private final MutablePropertySources propertySources;

private final DefaultResolver defaultResolver;

ConfigurationPropertySourcesPropertyResolver(MutablePropertySources propertySources) {
	this.propertySources = propertySources;
	this.defaultResolver = new DefaultResolver(propertySources);
}
创建默认的分解器

——————— DefaultResolver start

org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertyResolver$DefaultResolver

DefaultResolver(PropertySources propertySources) {
	super(propertySources);
}
查看父类构造方法

———————— PropertySourcesPropertyResolver start

org.springframework.core.env.PropertySourcesPropertyResolver

@Nullable
private final PropertySources propertySources;

public PropertySourcesPropertyResolver(@Nullable PropertySources propertySources) {
	this.propertySources = propertySources;
}

———————— PropertySourcesPropertyResolver end
——————— DefaultResolver end
—————— ConfigurationPropertySourcesPropertyResolver end
————— createPropertyResolver end
———— createPropertyResolver end

定制属性资源

———— customizePropertySources start

org.springframework.core.env.StandardEnvironment

public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";

public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";

@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()));
}
获取系统属性并添加
propertySources.addLast(
		new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));

————— getSystemProperties start

org.springframework.core.env.AbstractEnvironment

@Override
@SuppressWarnings({"rawtypes", "unchecked"})
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;
				}
			}
		};
	}
}

————— getSystemProperties end

获取系统环境并添加
propertySources.addLast(
		new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));

————— getSystemEnvironment start

org.springframework.core.env.AbstractEnvironment

@Override
@SuppressWarnings({"rawtypes", "unchecked"})
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;
				}
			}
		};
	}
}

————— getSystemEnvironment end
———— customizePropertySources end
——— AbstractEnvironment end
—— getOrCreateEnvironment end

配置环境

configureEnvironment(environment, applicationArguments.getSourceArgs());

注意此处getSourceArgs方法获取的为原始参数集合(String[]),并非处理后的实例(org.springframework.core.env.CommandLineArgs
—— configureEnvironment start

org.springframework.boot.SpringApplication

private boolean addConversionService = true;

protected void configureEnvironment(ConfigurableEnvironment environment, String[] args) {
	if (this.addConversionService) {
		environment.setConversionService(new ApplicationConversionService());
	}
	configurePropertySources(environment, args);
	configureProfiles(environment, args);
}

设置转换服务

environment.setConversionService(new ApplicationConversionService());
创建转换服务实例

——— ApplicationConversionService start

org.springframework.boot.convert.ApplicationConversionService

private final boolean unmodifiable;

public ApplicationConversionService() {
	this(null);
}

public ApplicationConversionService(StringValueResolver embeddedValueResolver) {
	this(embeddedValueResolver, false);
}

private ApplicationConversionService(StringValueResolver embeddedValueResolver, boolean unmodifiable) {
	if (embeddedValueResolver != null) {
		setEmbeddedValueResolver(embeddedValueResolver);
	}
	configure(this);
	this.unmodifiable = unmodifiable;
}
设置内嵌值分解器
setEmbeddedValueResolver(embeddedValueResolver);

———— setEmbeddedValueResolver start

org.springframework.format.support.FormattingConversionService

@Nullable
private StringValueResolver embeddedValueResolver;

@Override
public void setEmbeddedValueResolver(StringValueResolver resolver) {
	this.embeddedValueResolver = resolver;
}

此处分解器为null,无需设置
———— setEmbeddedValueResolver end

配置自身实例
configure(this);

———— configure start

org.springframework.boot.convert.ApplicationConversionService

public static void configure(FormatterRegistry registry) {
	DefaultConversionService.addDefaultConverters(registry);
	DefaultFormattingConversionService.addDefaultFormatters(registry);
	addApplicationFormatters(registry);
	addApplicationConverters(registry);
}
添加默认的转换器
DefaultConversionService.addDefaultConverters(registry);

————— addDefaultConverters start

org.springframework.core.convert.support.DefaultConversionService

public static void addDefaultConverters(ConverterRegistry converterRegistry) {
	addScalarConverters(converterRegistry);
	addCollectionConverters(converterRegistry);

	converterRegistry.addConverter(new ByteBufferConverter((ConversionService) converterRegistry));
	converterRegistry.addConverter(new StringToTimeZoneConverter());
	converterRegistry.addConverter(new ZoneIdToTimeZoneConverter());
	converterRegistry.addConverter(new ZonedDateTimeToCalendarConverter());

	converterRegistry.addConverter(new ObjectToObjectConverter());
	converterRegistry.addConverter(new IdToEntityConverter((ConversionService) converterRegistry));
	converterRegistry.addConverter(new FallbackObjectToStringConverter());
	converterRegistry.addConverter(new ObjectToOptionalConverter((ConversionService) converterRegistry));
}
添加标量转换器

—————— addScalarConverters start

org.springframework.core.convert.support.DefaultConversionService

private static void addScalarConverters(ConverterRegistry converterRegistry) {
	converterRegistry.addConverterFactory(new NumberToNumberConverterFactory());

	converterRegistry.addConverterFactory(new StringToNumberConverterFactory());
	converterRegistry.addConverter(Number.class, String.class, new ObjectToStringConverter());

	converterRegistry.addConverter(new StringToCharacterConverter());
	converterRegistry.addConverter(Character.class, String.class, new ObjectToStringConverter());

	converterRegistry.addConverter(new NumberToCharacterConverter());
	converterRegistry.addConverterFactory(new CharacterToNumberFactory());

	converterRegistry.addConverter(new StringToBooleanConverter());
	converterRegistry.addConverter(Boolean.class, String.class, new ObjectToStringConverter());

	converterRegistry.addConverterFactory(new StringToEnumConverterFactory());
	converterRegistry.addConverter(new EnumToStringConverter((ConversionService) converterRegistry));

	converterRegistry.addConverterFactory(new IntegerToEnumConverterFactory());
	converterRegistry.addConverter(new EnumToIntegerConverter((ConversionService) converterRegistry));

	converterRegistry.addConverter(new StringToLocaleConverter());
	converterRegistry.addConverter(Locale.class, String.class, new ObjectToStringConverter());

	converterRegistry.addConverter(new StringToCharsetConverter());
	converterRegistry.addConverter(Charset.class, String.class, new ObjectToStringConverter());

	converterRegistry.addConverter(new StringToCurrencyConverter());
	converterRegistry.addConverter(Currency.class, String.class, new ObjectToStringConverter());

	converterRegistry.addConverter(new StringToPropertiesConverter());
	converterRegistry.addConverter(new PropertiesToStringConverter());

	converterRegistry.addConverter(new StringToUUIDConverter());
	converterRegistry.addConverter(UUID.class, String.class, new ObjectToStringConverter());
}

—————— addScalarConverters end

添加集合转换器

—————— addCollectionConverters start

org.springframework.core.convert.support.DefaultConversionService

public static void addCollectionConverters(ConverterRegistry converterRegistry) {
	ConversionService conversionService = (ConversionService) converterRegistry;

	converterRegistry.addConverter(new ArrayToCollectionConverter(conversionService));
	converterRegistry.addConverter(new CollectionToArrayConverter(conversionService));

	converterRegistry.addConverter(new ArrayToArrayConverter(conversionService));
	converterRegistry.addConverter(new CollectionToCollectionConverter(conversionService));
	converterRegistry.addConverter(new MapToMapConverter(conversionService));

	converterRegistry.addConverter(new ArrayToStringConverter(conversionService));
	converterRegistry.addConverter(new StringToArrayConverter(conversionService));

	converterRegistry.addConverter(new ArrayToObjectConverter(conversionService));
	converterRegistry.addConverter(new ObjectToArrayConverter(conversionService));

	converterRegistry.addConverter(new CollectionToStringConverter(conversionService));
	converterRegistry.addConverter(new StringToCollectionConverter(conversionService));

	converterRegistry.addConverter(new CollectionToObjectConverter(conversionService));
	converterRegistry.addConverter(new ObjectToCollectionConverter(conversionService));

	converterRegistry.addConverter(new StreamConverter(conversionService));
}

—————— addCollectionConverters end
————— addDefaultConverters end

添加默认的格式器
DefaultFormattingConversionService.addDefaultFormatters(registry);

————— addDefaultFormatters start

org.springframework.format.support.DefaultFormattingConversionService

public static void addDefaultFormatters(FormatterRegistry formatterRegistry) {
	// Default handling of number values
	formatterRegistry.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());

	// Default handling of monetary values
	if (jsr354Present) {
		formatterRegistry.addFormatter(new CurrencyUnitFormatter());
		formatterRegistry.addFormatter(new MonetaryAmountFormatter());
		formatterRegistry.addFormatterForFieldAnnotation(new Jsr354NumberFormatAnnotationFormatterFactory());
	}

	// Default handling of date-time values

	// just handling JSR-310 specific date and time types
	new DateTimeFormatterRegistrar().registerFormatters(formatterRegistry);

	if (jodaTimePresent) {
		// handles Joda-specific types as well as Date, Calendar, Long
		new org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar().registerFormatters(formatterRegistry);
	}
	else {
		// regular DateFormat-based Date, Calendar, Long converters
		new DateFormatterRegistrar().registerFormatters(formatterRegistry);
	}
}

主要为时间和货币的格式化器、注解工厂等
addFormatterForFieldAnnotation方法用于添加成员属性的格式化注解
—————— addFormatterForFieldAnnotation start

org.springframework.boot.convert.ApplicationConversionService

@Override
public void addFormatterForFieldAnnotation(
		AnnotationFormatterFactory<? extends Annotation> annotationFormatterFactory) {
	assertModifiable();
	super.addFormatterForFieldAnnotation(annotationFormatterFactory);
}
验证是否可修改
assertModifiable();

——————— assertModifiable start

org.springframework.boot.convert.ApplicationConversionService

private void assertModifiable() {
	if (this.unmodifiable) {
		throw new UnsupportedOperationException("This ApplicationConversionService cannot be modified");
	}
}

——————— assertModifiable end
其他添加方法也均调用assertModifiable方法验证

调用父类方法
super.addFormatterForFieldAnnotation(annotationFormatterFactory);

——————— addFormatterForFieldAnnotation start

org.springframework.format.support.FormattingConversionService

@Override
public void addFormatterForFieldAnnotation(AnnotationFormatterFactory<? extends Annotation> annotationFormatterFactory) {
	Class<? extends Annotation> annotationType = getAnnotationType(annotationFormatterFactory);
	if (this.embeddedValueResolver != null && annotationFormatterFactory instanceof EmbeddedValueResolverAware) {
		((EmbeddedValueResolverAware) annotationFormatterFactory).setEmbeddedValueResolver(this.embeddedValueResolver);
	}
	Set<Class<?>> fieldTypes = annotationFormatterFactory.getFieldTypes();
	for (Class<?> fieldType : fieldTypes) {
		addConverter(new AnnotationPrinterConverter(annotationType, annotationFormatterFactory, fieldType));
		addConverter(new AnnotationParserConverter(annotationType, annotationFormatterFactory, fieldType));
	}
}
获取注解类型
Class<? extends Annotation> annotationType = getAnnotationType(annotationFormatterFactory);

———————— getAnnotationType start

org.springframework.format.support.FormattingConversionService

@SuppressWarnings("unchecked")
static Class<? extends Annotation> getAnnotationType(AnnotationFormatterFactory<? extends Annotation> factory) {
	Class<? extends Annotation> annotationType = (Class<? extends Annotation>)
			GenericTypeResolver.resolveTypeArgument(factory.getClass(), AnnotationFormatterFactory.class);
	if (annotationType == null) {
		throw new IllegalArgumentException("Unable to extract parameterized Annotation type argument from " +
				"AnnotationFormatterFactory [" + factory.getClass().getName() +
				"]; does the factory parameterize the <A extends Annotation> generic type?");
	}
	return annotationType;
}
获取类型
Class<? extends Annotation> annotationType = (Class<? extends Annotation>)
		GenericTypeResolver.resolveTypeArgument(factory.getClass(), AnnotationFormatterFactory.class);

————————— resolveTypeArgument start

org.springframework.core.GenericTypeResolver

@Nullable
public static Class<?> resolveTypeArgument(Class<?> clazz, Class<?> genericIfc) {
	ResolvableType resolvableType = ResolvableType.forClass(clazz).as(genericIfc);
	if (!resolvableType.hasGenerics()) {
		return null;
	}
	return getSingleGeneric(resolvableType);
}
获取类型信息
ResolvableType resolvableType = ResolvableType.forClass(clazz).as(genericIfc);

可知此时获取的为工厂实例作为org.springframework.format.AnnotationFormatterFactory的信息

获取单个泛型
return getSingleGeneric(resolvableType);

—————————— getSingleGeneric start

org.springframework.core.GenericTypeResolver

@Nullable
private static Class<?> getSingleGeneric(ResolvableType resolvableType) {
	Assert.isTrue(resolvableType.getGenerics().length == 1,
			() -> "Expected 1 type argument on generic interface [" + resolvableType +
			"] but found " + resolvableType.getGenerics().length);
	return resolvableType.getGeneric().resolve();
}

—————————— getSingleGeneric end
返回工厂作为org.springframework.format.AnnotationFormatterFactory时的泛型
————————— resolveTypeArgument end

验证后返回
if (annotationType == null) {
	throw new IllegalArgumentException("Unable to extract parameterized Annotation type argument from " +
			"AnnotationFormatterFactory [" + factory.getClass().getName() +
			"]; does the factory parameterize the <A extends Annotation> generic type?");
}
return annotationType;

———————— getAnnotationType end

设置内嵌值分解器
if (this.embeddedValueResolver != null && annotationFormatterFactory instanceof EmbeddedValueResolverAware) {
	((EmbeddedValueResolverAware) annotationFormatterFactory).setEmbeddedValueResolver(this.embeddedValueResolver);
}

由前文可知,embeddedValueResolvernull

获取成员属性的类型集合
Set<Class<?>> fieldTypes = annotationFormatterFactory.getFieldTypes();

此处以org.springframework.format.number.NumberFormatAnnotationFormatterFactory为例
———————— getFieldTypes start

org.springframework.format.number.NumberFormatAnnotationFormatterFactory

@Override
public Set<Class<?>> getFieldTypes() {
	return NumberUtils.STANDARD_NUMBER_TYPES;
}
org.springframework.util.NumberUtils

public static final Set<Class<?>> STANDARD_NUMBER_TYPES;

static {
	Set<Class<?>> numberTypes = new HashSet<>(8);
	numberTypes.add(Byte.class);
	numberTypes.add(Short.class);
	numberTypes.add(Integer.class);
	numberTypes.add(Long.class);
	numberTypes.add(BigInteger.class);
	numberTypes.add(Float.class);
	numberTypes.add(Double.class);
	numberTypes.add(BigDecimal.class);
	STANDARD_NUMBER_TYPES = Collections.unmodifiableSet(numberTypes);
}

———————— getFieldTypes end

遍历集合添加打印器和解析器
for (Class<?> fieldType : fieldTypes) {
	addConverter(new AnnotationPrinterConverter(annotationType, annotationFormatterFactory, fieldType));
	addConverter(new AnnotationParserConverter(annotationType, annotationFormatterFactory, fieldType));
}
创建注解打印器转换器

———————— AnnotationPrinterConverter start

org.springframework.format.support.FormattingConversionService$AnnotationPrinterConverter

private final Class<? extends Annotation> annotationType;

@SuppressWarnings("rawtypes")
private final AnnotationFormatterFactory annotationFormatterFactory;

private final Class<?> fieldType;

public AnnotationPrinterConverter(Class<? extends Annotation> annotationType,
		AnnotationFormatterFactory<?> annotationFormatterFactory, Class<?> fieldType) {

	this.annotationType = annotationType;
	this.annotationFormatterFactory = annotationFormatterFactory;
	this.fieldType = fieldType;
}

———————— AnnotationPrinterConverter end

创建注解解析器转换器

———————— AnnotationParserConverter start

org.springframework.format.support.FormattingConversionService$AnnotationParserConverter

private final Class<? extends Annotation> annotationType;

@SuppressWarnings("rawtypes")
private final AnnotationFormatterFactory annotationFormatterFactory;

private final Class<?> fieldType;

public AnnotationParserConverter(Class<? extends Annotation> annotationType,
		AnnotationFormatterFactory<?> annotationFormatterFactory, Class<?> fieldType) {

	this.annotationType = annotationType;
	this.annotationFormatterFactory = annotationFormatterFactory;
	this.fieldType = fieldType;
}

———————— AnnotationParserConverter end
addConverter方法用于添加转换器,与前面的addFormatterForFieldAnnotation方法类似
———————— addConverter start

org.springframework.boot.convert.ApplicationConversionService

@Override
public void addConverter(GenericConverter converter) {
	assertModifiable();
	super.addConverter(converter);
}
验证可修改
assertModifiable();
调用父类方法
super.addConverter(converter);

————————— addConverter start

org.springframework.core.convert.support.GenericConversionService

private final Converters converters = new Converters();

@Override
public void addConverter(GenericConverter converter) {
	this.converters.add(converter);
	invalidateCache();
}
添加转换器
this.converters.add(converter);

—————————— add start

org.springframework.core.convert.support.GenericConversionService$Converters

private final Set<GenericConverter> globalConverters = new CopyOnWriteArraySet<>();

public void add(GenericConverter converter) {
	Set<ConvertiblePair> convertibleTypes = converter.getConvertibleTypes();
	if (convertibleTypes == null) {
		Assert.state(converter instanceof ConditionalConverter,
				"Only conditional converters may return null convertible types");
		this.globalConverters.add(converter);
	}
	else {
		for (ConvertiblePair convertiblePair : convertibleTypes) {
			getMatchableConverters(convertiblePair).add(converter);
		}
	}
}
获取可转换类型集合
Set<ConvertiblePair> convertibleTypes = converter.getConvertibleTypes();

——————————— getConvertibleTypes start

org.springframework.format.support.FormattingConversionService$AnnotationPrinterConverter

@Override
public Set<ConvertiblePair> getConvertibleTypes() {
	return Collections.singleton(new ConvertiblePair(this.fieldType, String.class));
}
创建可转换对
new ConvertiblePair(this.fieldType, String.class)

——————————— ConvertiblePair start

org.springframework.core.convert.converter.GenericConverter$ConvertiblePair

private final Class<?> sourceType;

private final Class<?> targetType;

public ConvertiblePair(Class<?> sourceType, Class<?> targetType) {
	Assert.notNull(sourceType, "Source type must not be null");
	Assert.notNull(targetType, "Target type must not be null");
	this.sourceType = sourceType;
	this.targetType = targetType;
}

——————————— ConvertiblePair end

创建集合并返回

—————————— getConvertibleTypes end

添加转换器

由于上一步获取的类型集合不为空,遍历并加入

for (ConvertiblePair convertiblePair : convertibleTypes) {
	getMatchableConverters(convertiblePair).add(converter);
}
获取匹配的转换器集合

——————————— getMatchableConverters start

org.springframework.core.convert.support.GenericConversionService$Converters

private final Map<ConvertiblePair, ConvertersForPair> converters = new ConcurrentHashMap<>(256);

private ConvertersForPair getMatchableConverters(ConvertiblePair convertiblePair) {
	return this.converters.computeIfAbsent(convertiblePair, k -> new ConvertersForPair());
}

convertiblePair为键,返回或创建实例
——————————— getMatchableConverters end

添加至转换器

——————————— add start

org.springframework.core.convert.support.GenericConversionService$ConvertersForPair

private final Deque<GenericConverter> converters = new ConcurrentLinkedDeque<>();

public void add(GenericConverter converter) {
	this.converters.addFirst(converter);
}

——————————— add end
—————————— add end

清理缓存
invalidateCache();

—————————— invalidateCache start

org.springframework.core.convert.support.GenericConversionService

private final Map<ConverterCacheKey, GenericConverter> converterCache = new ConcurrentReferenceHashMap<>(64);

private void invalidateCache() {
	this.converterCache.clear();
}

—————————— invalidateCache end
————————— addConverter end
———————— addConverter end
——————— addFormatterForFieldAnnotation end
—————— addFormatterForFieldAnnotation end
————— addDefaultFormatters end

添加应用格式器
addApplicationFormatters(registry);

————— addApplicationFormatters start

org.springframework.boot.convert.ApplicationConversionService

public static void addApplicationFormatters(FormatterRegistry registry) {
	registry.addFormatter(new CharArrayFormatter());
	registry.addFormatter(new InetAddressFormatter());
	registry.addFormatter(new IsoOffsetFormatter());
}

————— addApplicationFormatters end

添加应用转换器
addApplicationConverters(registry);

————— addApplicationConverters start

org.springframework.boot.convert.ApplicationConversionService

public static void addApplicationConverters(ConverterRegistry registry) {
	addDelimitedStringConverters(registry);
	registry.addConverter(new StringToDurationConverter());
	registry.addConverter(new DurationToStringConverter());
	registry.addConverter(new NumberToDurationConverter());
	registry.addConverter(new DurationToNumberConverter());
	registry.addConverter(new StringToPeriodConverter());
	registry.addConverter(new PeriodToStringConverter());
	registry.addConverter(new NumberToPeriodConverter());
	registry.addConverter(new StringToDataSizeConverter());
	registry.addConverter(new NumberToDataSizeConverter());
	registry.addConverter(new StringToFileConverter());
	registry.addConverter(new InputStreamSourceToByteArrayConverter());
	registry.addConverterFactory(new LenientStringToEnumConverterFactory());
	registry.addConverterFactory(new LenientBooleanToEnumConverterFactory());
	if (registry instanceof ConversionService) {
		addApplicationConverters(registry, (ConversionService) registry);
	}
}
添加分隔字符串转换器
addDelimitedStringConverters(registry);

—————— addDelimitedStringConverters start

org.springframework.boot.convert.ApplicationConversionService

public static void addDelimitedStringConverters(ConverterRegistry registry) {
	ConversionService service = (ConversionService) registry;
	registry.addConverter(new ArrayToDelimitedStringConverter(service));
	registry.addConverter(new CollectionToDelimitedStringConverter(service));
	registry.addConverter(new DelimitedStringToArrayConverter(service));
	registry.addConverter(new DelimitedStringToCollectionConverter(service));
}

用于字符串和集合/数组间转换
—————— addDelimitedStringConverters end

添加最后的转换器
addApplicationConverters(registry, (ConversionService) registry);

—————— addApplicationConverters start

org.springframework.boot.convert.ApplicationConversionService

private static void addApplicationConverters(ConverterRegistry registry, ConversionService conversionService) {
	registry.addConverter(new CharSequenceToObjectConverter(conversionService));
}

org.springframework.boot.convert.CharSequenceToObjectConverter其本质为代理,使用代理实例的转换器
—————— addApplicationConverters end
这里代理了实例本身,可使用已注册的转换器
————— addApplicationConverters end
———— configure end

设置是否可修改
this.unmodifiable = unmodifiable;

unmodifiablefalse,表示当前实例可修改,后面会看到
——— ApplicationConversionService end
org.springframework.boot.convert.ApplicationConversionService创建完成
——— setConversionService start

org.springframework.core.env.AbstractEnvironment

@Override
public void setConversionService(ConfigurableConversionService conversionService) {
	this.propertyResolver.setConversionService(conversionService);
}

———— setConversionService start

org.springframework.core.env.AbstractPropertyResolver

@Nullable
private volatile ConfigurableConversionService conversionService;

@Override
public void setConversionService(ConfigurableConversionService conversionService) {
	Assert.notNull(conversionService, "ConversionService must not be null");
	this.conversionService = conversionService;
}

———— setConversionService end
——— setConversionService end

配置属性资源

configurePropertySources(environment, args);

——— configurePropertySources start

org.springframework.boot.SpringApplication

private boolean addCommandLineProperties = true;

private Map<String, Object> defaultProperties;

protected void configurePropertySources(ConfigurableEnvironment environment, String[] args) {
	MutablePropertySources sources = environment.getPropertySources();
	if (!CollectionUtils.isEmpty(this.defaultProperties)) {
		DefaultPropertiesPropertySource.addOrMerge(this.defaultProperties, sources);
	}
	if (this.addCommandLineProperties && args.length > 0) {
		String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME;
		if (sources.contains(name)) {
			PropertySource<?> source = sources.get(name);
			CompositePropertySource composite = new CompositePropertySource(name);
			composite.addPropertySource(
					new SimpleCommandLinePropertySource("springApplicationCommandLineArgs", args));
			composite.addPropertySource(source);
			sources.replace(name, composite);
		}
		else {
			sources.addFirst(new SimpleCommandLinePropertySource(args));
		}
	}
}
获取前面创建的属性资源
MutablePropertySources sources = environment.getPropertySources();

包括系统属性和系统环境

添加默认的属性
if (!CollectionUtils.isEmpty(this.defaultProperties)) {
	DefaultPropertiesPropertySource.addOrMerge(this.defaultProperties, sources);
}

默认属性为null

添加命令行属性资源
当存在命令行参数时
if (this.addCommandLineProperties && args.length > 0)
获取命令行属性资源名称
String name = CommandLinePropertySource.COMMAND_LINE_PROPERTY_SOURCE_NAME;

commandLineArgs

若资已包含,则以springApplicationCommandLineArgs之名创建新的命令行属性资源,与原本的命令行属性资源整合
PropertySource<?> source = sources.get(name);
CompositePropertySource composite = new CompositePropertySource(name);
composite.addPropertySource(
		new SimpleCommandLinePropertySource("springApplicationCommandLineArgs", args));
composite.addPropertySource(source);
sources.replace(name, composite);
不包含则直接添加
sources.addFirst(new SimpleCommandLinePropertySource(args));

——— configurePropertySources end

配置概述

configureProfiles(environment, args);

——— configureProfiles start

protected void configureProfiles(ConfigurableEnvironment environment, String[] args) {
}

此为空方法
——— configureProfiles end
—— configureEnvironment end

将属性资源附加于环境实例

ConfigurationPropertySources.attach(environment);

—— attach start

org.springframework.boot.context.properties.source.ConfigurationPropertySources

public static void attach(Environment environment) {
	Assert.isInstanceOf(ConfigurableEnvironment.class, environment);
	MutablePropertySources sources = ((ConfigurableEnvironment) environment).getPropertySources();
	PropertySource<?> attached = getAttached(sources);
	if (attached == null || !isUsingSources(attached, sources)) {
		attached = new ConfigurationPropertySourcesPropertySource(ATTACHED_PROPERTY_SOURCE_NAME,
				new SpringConfigurationPropertySources(sources));
	}
	sources.remove(ATTACHED_PROPERTY_SOURCE_NAME);
	sources.addFirst(attached);
}

获取属性资源

MutablePropertySources sources = ((ConfigurableEnvironment) environment).getPropertySources();

——— getPropertySources start

org.springframework.core.env.AbstractEnvironment

@Override
public MutablePropertySources getPropertySources() {
	return this.propertySources;
}

propertySources于上文的构造方法内设置
——— getPropertySources end

获取附加的属性资源

PropertySource<?> attached = getAttached(sources);

——— getAttached start

org.springframework.boot.context.properties.source.ConfigurationPropertySources

private static final String ATTACHED_PROPERTY_SOURCE_NAME = "configurationProperties";

static PropertySource<?> getAttached(MutablePropertySources sources) {
	return (sources != null) ? sources.get(ATTACHED_PROPERTY_SOURCE_NAME) : null;
}

——— getAttached end
当前attachednull

判断是否使用资源

isUsingSources(attached, sources)

——— isUsingSources start

org.springframework.boot.context.properties.source.ConfigurationPropertySources

private static boolean isUsingSources(PropertySource<?> attached, MutablePropertySources sources) {
	return attached instanceof ConfigurationPropertySourcesPropertySource
			&& ((SpringConfigurationPropertySources) attached.getSource()).isUsingSources(sources);
}
判断attached类后获取其资源实例并转换

———— isUsingSources start

org.springframework.boot.context.properties.source.SpringConfigurationPropertySources

boolean isUsingSources(Iterable<PropertySource<?>> sources) {
	return this.sources == sources;
}

———— isUsingSources end
最终比对实例地址是否相同
——— isUsingSources end

创建新的实例

attached = new ConfigurationPropertySourcesPropertySource(ATTACHED_PROPERTY_SOURCE_NAME,
		new SpringConfigurationPropertySources(sources));

———— SpringConfigurationPropertySources start

org.springframework.boot.context.properties.source.SpringConfigurationPropertySources

private final Iterable<PropertySource<?>> sources;

SpringConfigurationPropertySources(Iterable<PropertySource<?>> sources) {
	Assert.notNull(sources, "Sources must not be null");
	this.sources = sources;
}

———— SpringConfigurationPropertySources end
对应上文isUsingSources方法内对资源实例的强制类转换
———— ConfigurationPropertySourcesPropertySource start

org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource

ConfigurationPropertySourcesPropertySource(String name, Iterable<ConfigurationPropertySource> source) {
	super(name, source);
}
查看父类构造方法

————— PropertySource start

org.springframework.core.env.PropertySource

protected final String name;

protected final T source;

public PropertySource(String name, T source) {
	Assert.hasText(name, "Property source name must contain at least one character");
	Assert.notNull(source, "Property source must not be null");
	this.name = name;
	this.source = source;
}

————— PropertySource end
———— ConfigurationPropertySourcesPropertySource end
对应上文isUsingSources方法内对attach类型判断

从资源实例移除原本的实例

sources.remove(ATTACHED_PROPERTY_SOURCE_NAME);

添加至资源实例

sources.addFirst(attached);

—— attach end

监听器的环境准备

listeners.environmentPrepared(bootstrapContext, environment);

—— environmentPrepared start

org.springframework.boot.SpringApplicationRunListeners

void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
	doWithListeners("spring.boot.application.environment-prepared",
			(listener) -> listener.environmentPrepared(bootstrapContext, environment));
}

类似于之前的启动方法,关注运行监听器的environmentPrepared方法即可
——— environmentPrepared start

org.springframework.boot.context.event.EventPublishingRunListener

@Override
public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,
		ConfigurableEnvironment environment) {
	this.initialMulticaster.multicastEvent(
			new ApplicationEnvironmentPreparedEvent(bootstrapContext, this.application, this.args, environment));
}

创建org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent事件实例并交由匹配的监听器的onApplicationEvent方法处理
当前匹配的监听器共6
org.springframework.boot.env.EnvironmentPostProcessorApplicationListener
org.springframework.boot.context.config.AnsiOutputApplicationListener
org.springframework.boot.context.logging.LoggingApplicationListener
org.springframework.boot.autoconfigure.BackgroundPreinitializer
org.springframework.boot.context.config.DelegatingApplicationListener
org.springframework.boot.context.FileEncodingApplicationListener
由于篇幅问题,将监听器的执行放在后文
——— environmentPrepared end
—— environmentPrepared end
— prepareEnvironment end

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值