Author: HuiFer
源码阅读仓库: SourceHot-spring-boot
本文主要对
org.springframework.boot.context.properties.ConfigurationProperties
进行分析
- 顶部注释
* @seeConfigurationPropertiesScan * @seeConstructorBinding * @seeConfigurationPropertiesBindingPostProcessor * @seeEnableConfigurationProperties
看到ConfigurationPropertiesScan
去看看这个
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented@Import(ConfigurationPropertiesScanRegistrar.class) @EnableConfigurationPropertiespublic @interface ConfigurationPropertiesScan {}
- 熟悉的Import注解
- debug 没有抓到后续补充
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented@Import(EnableConfigurationPropertiesRegistrar.class) public @interface EnableConfigurationProperties { }
该类会读取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); }
staticvoidregisterInfrastructureBeans(BeanDefinitionRegistryregistry) { // 属性绑定后置处理器ConfigurationPropertiesBindingPostProcessor.register(registry); // 属性校验器ConfigurationPropertiesBeanDefinitionValidator.register(registry); ConfigurationBeanFactoryMetadata.register(registry); }
- 此处操作逻辑基本相同,是否存在这个 beanName 存在直接注册,不存在补充
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); }
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); }
- 先看输入参数 metadata
- getTypes 结果
源码开始,先找出刚才的对象
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); }
@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(); }
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
bindType
- 返回对象
- 此时数据还没有进去
- 数据绑定
直接看结果
- 上述配置和我在配置文件中写的配置一致
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); }
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); }
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; }
- 最终获取得到的处理器
- 最后的 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); }
配置信息到此绑定成功,关于如何处理集合相关的配置请各位读者自行学习