Skip to content

Latest commit

History

History
505 lines (400 loc) · 16.7 KB

File metadata and controls

505 lines (400 loc) · 16.7 KB

SpringBoot ConfigurationProperties

  • Author: HuiFer

  • 源码阅读仓库: SourceHot-spring-boot

  • 本文主要对org.springframework.boot.context.properties.ConfigurationProperties进行分析

ConfigurationProperties

  • 顶部注释
 * @seeConfigurationPropertiesScan
* @seeConstructorBinding
* @seeConfigurationPropertiesBindingPostProcessor
* @seeEnableConfigurationProperties

看到ConfigurationPropertiesScan 去看看这个

ConfigurationPropertiesScan

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented@Import(ConfigurationPropertiesScanRegistrar.class)
@EnableConfigurationPropertiespublic @interface ConfigurationPropertiesScan {}
  • 熟悉的Import注解

ConfigurationPropertiesScanRegistrar

image-20200323094446756

  • debug 没有抓到后续补充

EnableConfigurationProperties

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented@Import(EnableConfigurationPropertiesRegistrar.class)
public @interface EnableConfigurationProperties {
}

EnableConfigurationPropertiesRegistrar

  • 该类会读取spring.factories

  • org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 这样的

    org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration
    org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletConfiguration
    org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletRegistrationConfiguration
    org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration
    org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
    org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration$WebMvcAutoConfigurationAdapter
    org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration
    org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration$Jackson2ObjectMapperBuilderCustomizerConfiguration
    org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration$StringHttpMessageConverterConfiguration
    org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration
    org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration
    org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration
    org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration
    org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration
    org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration
    
@OverridepublicvoidregisterBeanDefinitions(AnnotationMetadatametadata, BeanDefinitionRegistryregistry) {
// 注册beanregisterInfrastructureBeans(registry);
// 配置属性Bean注册器ConfigurationPropertiesBeanRegistrarbeanRegistrar = newConfigurationPropertiesBeanRegistrar(registry);
// 循环注册getTypes(metadata).forEach(beanRegistrar::register);
}

registerInfrastructureBeans

staticvoidregisterInfrastructureBeans(BeanDefinitionRegistryregistry) {
// 属性绑定后置处理器ConfigurationPropertiesBindingPostProcessor.register(registry);
// 属性校验器ConfigurationPropertiesBeanDefinitionValidator.register(registry);
ConfigurationBeanFactoryMetadata.register(registry);
}
  • 此处操作逻辑基本相同,是否存在这个 beanName 存在直接注册,不存在补充

ConfigurationPropertiesBindingPostProcessor.register(registry)

publicstaticvoidregister(BeanDefinitionRegistryregistry) {
Assert.notNull(registry, "Registry must not be null");
// 是否存在if (!registry.containsBeanDefinition(BEAN_NAME)) {
GenericBeanDefinitiondefinition = newGenericBeanDefinition();
definition.setBeanClass(ConfigurationPropertiesBindingPostProcessor.class);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(BEAN_NAME, definition);
}
ConfigurationPropertiesBinder.register(registry);
}

ConfigurationPropertiesBeanDefinitionValidator.register(registry)

staticvoidregister(BeanDefinitionRegistryregistry) {
Assert.notNull(registry, "Registry must not be null");
if (!registry.containsBeanDefinition(BEAN_NAME)) {
GenericBeanDefinitiondefinition = newGenericBeanDefinition();
definition.setBeanClass(ConfigurationPropertiesBeanDefinitionValidator.class);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(BEAN_NAME, definition);
}
ConfigurationPropertiesBinder.register(registry);
}

getTypes(metadata).forEach(beanRegistrar::register)

  • 先看输入参数 metadata

image-20200323134135926

  • getTypes 结果

image-20200323134325955

  • 源码开始,先找出刚才的对象org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration

    @Configuration(proxyBeanMethods = false)
    @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
    @ConditionalOnClass(ServletRequest.class)
    @ConditionalOnWebApplication(type = Type.SERVLET)
    @EnableConfigurationProperties(ServerProperties.class)
    @Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
    ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
    ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
    ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
    publicclassServletWebServerFactoryAutoConfiguration {}
/** * 找出 {@link EnableConfigurationProperties} 注解标记的中的属性值,并且返回值不是void * @param metadata * @return */privateSet<Class<?>> getTypes(AnnotationMetadatametadata) {
returnmetadata.getAnnotations().stream(EnableConfigurationProperties.class)
.flatMap((annotation) -> Arrays.stream(annotation.getClassArray(MergedAnnotation.VALUE)))
.filter((type) -> void.class != type).collect(Collectors.toSet());
}
  • 这里我们可以直接知道返回的是@EnableConfigurationProperties(ServerProperties.class) 的数据值: ServerProperties.class

循环注册

voidregister(Class<?> type) {
MergedAnnotation<ConfigurationProperties> annotation = MergedAnnotations
.from(type, SearchStrategy.TYPE_HIERARCHY).get(ConfigurationProperties.class);
register(type, annotation);
}

ConfigurationPropertiesBindingPostProcessor

image-20200323095626953

postProcessBeforeInitialization

@OverridepublicObjectpostProcessBeforeInitialization(Objectbean, StringbeanName) throwsBeansException {
// 绑定bind(ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName));
returnbean;
}
  • get

    publicstaticConfigurationPropertiesBeanget(ApplicationContextapplicationContext, Objectbean, StringbeanName) {
    // 寻找工厂方法MethodfactoryMethod = findFactoryMethod(applicationContext, beanName);
    // 创建 ConfigurationPropertiesBeanreturncreate(beanName, bean, bean.getClass(), factoryMethod);
    }
privatestaticMethodfindFactoryMethod(ConfigurableListableBeanFactorybeanFactory, StringbeanName) {
// 判断是否存在这个beanNameif (beanFactory.containsBeanDefinition(beanName)) {
// 获取bean定义BeanDefinitionbeanDefinition = beanFactory.getMergedBeanDefinition(beanName);
// 类型判断if (beanDefinitioninstanceofRootBeanDefinition) {
// 解析方法MethodresolvedFactoryMethod = ((RootBeanDefinition) beanDefinition).getResolvedFactoryMethod();
if (resolvedFactoryMethod != null) {
returnresolvedFactoryMethod;
}
}
returnfindFactoryMethodUsingReflection(beanFactory, beanDefinition);
}
returnnull;
}
privatestaticMethodfindFactoryMethodUsingReflection(ConfigurableListableBeanFactorybeanFactory,
BeanDefinitionbeanDefinition) {
// 工厂方法StringfactoryMethodName = beanDefinition.getFactoryMethodName();
// 工厂beanStringfactoryBeanName = beanDefinition.getFactoryBeanName();
if (factoryMethodName == null || factoryBeanName == null) {
returnnull;
}
// 转换对象Class<?> factoryType = beanFactory.getType(factoryBeanName);
if (factoryType.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
factoryType = factoryType.getSuperclass();
}
AtomicReference<Method> factoryMethod = newAtomicReference<>();
ReflectionUtils.doWithMethods(factoryType, (method) -> {
// 判断是否是需要的方法if (method.getName().equals(factoryMethodName)) {
// 设置方法factoryMethod.set(method);
}
});
// 返回方法returnfactoryMethod.get();
}

create

  • org.springframework.boot.context.properties.ConfigurationPropertiesBean#create
privatestaticConfigurationPropertiesBeancreate(Stringname, Objectinstance, Class<?> type, Methodfactory) {
// 找注解ConfigurationPropertiesannotation = findAnnotation(instance, type, factory, ConfigurationProperties.class);
if (annotation == null) {
returnnull;
}
// 找注解Validatedvalidated = findAnnotation(instance, type, factory, Validated.class);
// 注解列表Annotation[] annotations = (validated != null) ? newAnnotation[] { annotation, validated }
: newAnnotation[] { annotation };
// 类型解析ResolvableTypebindType = (factory != null) ? ResolvableType.forMethodReturnType(factory)
: ResolvableType.forClass(type);
// 绑定结果对象Bindable<Object> bindTarget = Bindable.of(bindType).withAnnotations(annotations);
if (instance != null) {
bindTarget = bindTarget.withExistingValue(instance);
}
returnnewConfigurationPropertiesBean(name, instance, annotation, bindTarget);
}
  • 第一个需要做的类: org.springframework.boot.autoconfigure.web.ServerProperties

  • annotation

image-20200323104711545

  • bindType

image-20200323104815305

  • 返回对象

image-20200323105053757

  • 此时数据还没有进去

bind

  • 数据绑定

直接看结果

image-20200323105155998

  • 上述配置和我在配置文件中写的配置一致
server:
port: 9999
  • 具体方法: org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor#bind
privatevoidbind(ConfigurationPropertiesBeanbean) {
if (bean == null || hasBoundValueObject(bean.getName())) {
return;
}
Assert.state(bean.getBindMethod() == BindMethod.JAVA_BEAN, "Cannot bind @ConfigurationProperties for bean '"
+ bean.getName() + "'. Ensure that @ConstructorBinding has not been applied to regular bean");
try {
// 最终的绑定this.binder.bind(bean);
}
catch (Exceptionex) {
thrownewConfigurationPropertiesBindException(bean, ex);
}
}
BindResult<?> bind(ConfigurationPropertiesBeanpropertiesBean) {
// 最后的结果Bindable<?> target = propertiesBean.asBindTarget();
// 注解获取ConfigurationPropertiesannotation = propertiesBean.getAnnotation();
// 获取处理器BindHandlerbindHandler = getBindHandler(target, annotation);
//returngetBinder().bind(annotation.prefix(), target, bindHandler);
}

image-20200323105830138

findProperty
privateConfigurationPropertyfindProperty(ConfigurationPropertyNamename, Contextcontext) {
if (name.isEmpty()) {
returnnull;
}
for (ConfigurationPropertySourcesource : context.getSources()) {
// 获取具体的一个属性值ConfigurationPropertyproperty = source.getConfigurationProperty(name);
if (property != null) {
returnproperty;
}
}
returnnull;
}
  • org.springframework.boot.context.properties.source.SpringConfigurationPropertySource#getConfigurationProperty

    @OverridepublicConfigurationPropertygetConfigurationProperty(ConfigurationPropertyNamename) {
    PropertyMapping[] mappings = getMapper().map(name);
    returnfind(mappings, name);
    }
    protectedfinalConfigurationPropertyfind(PropertyMapping[] mappings, ConfigurationPropertyNamename) {
    for (PropertyMappingcandidate : mappings) {
    if (candidate.isApplicable(name)) {
    ConfigurationPropertyresult = find(candidate);
    if (result != null) {
    returnresult;
    }
    }
    }
    returnnull;
    }
    privateConfigurationPropertyfind(PropertyMappingmapping) {
    // 需要读取的配置信息的keyStringpropertySourceName = mapping.getPropertySourceName();
    // 信息的valueObjectvalue = getPropertySource().getProperty(propertySourceName);
    if (value == null) {
    returnnull;
    }
    // 创建对象ConfigurationPropertyNameconfigurationPropertyName = mapping.getConfigurationPropertyName();
    Originorigin = PropertySourceOrigin.get(this.propertySource, propertySourceName);
    // 包装返回returnConfigurationProperty.of(configurationPropertyName, value, origin);
    }

image-20200323115408877

image-20200323115701118

image-20200323115711826

getBindHandler
private <T> BindHandlergetBindHandler(Bindable<T> target, ConfigurationPropertiesannotation) {
// 获取校验接口列表List<Validator> validators = getValidators(target);
// 处理器BindHandlerhandler = newIgnoreTopLevelConverterNotFoundBindHandler();
if (annotation.ignoreInvalidFields()) {
// 忽略错误的绑定处理器handler = newIgnoreErrorsBindHandler(handler);
}
if (!annotation.ignoreUnknownFields()) {
UnboundElementsSourceFilterfilter = newUnboundElementsSourceFilter();
// 未绑定元素处理器handler = newNoUnboundElementsBindHandler(handler, filter);
}
if (!validators.isEmpty()) {
// 校验绑定处理器handler = newValidationBindHandler(handler, validators.toArray(newValidator[0]));
}
for (ConfigurationPropertiesBindHandlerAdvisoradvisor : getBindHandlerAdvisors()) {
// handlerhandler = advisor.apply(handler);
}
returnhandler;
}
  • 最终获取得到的处理器

image-20200323110603959

  • 最后的 bind
private <T> ObjectbindObject(ConfigurationPropertyNamename, Bindable<T> target, BindHandlerhandler,
Contextcontext, booleanallowRecursiveBinding) {
// 获取属性ConfigurationPropertyproperty = findProperty(name, context);
if (property == null && containsNoDescendantOf(context.getSources(), name) && context.depth != 0) {
returnnull;
}
AggregateBinder<?> aggregateBinder = getAggregateBinder(target, context);
if (aggregateBinder != null) {
returnbindAggregate(name, target, handler, context, aggregateBinder);
}
if (property != null) {
try {
returnbindProperty(target, context, property);
}
catch (ConverterNotFoundExceptionex) {
// We might still be able to bind it using the recursive bindersObjectinstance = bindDataObject(name, target, handler, context, allowRecursiveBinding);
if (instance != null) {
returninstance;
}
throwex;
}
}
returnbindDataObject(name, target, handler, context, allowRecursiveBinding);
}

image-20200323112945449

配置信息到此绑定成功,关于如何处理集合相关的配置请各位读者自行学习