@ConfigurationProperties(prefix = "luck")
@EnableConfigurationProperties(LuckProperties.class)
@Data
public class LuckProperties {
private String language;
}
@Import(EnableConfigurationPropertiesRegistrar.class)
public @interface EnableConfigurationProperties {
}
class EnableConfigurationPropertiesRegistrar {
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
registerInfrastructureBeans(registry) {
// 处理属性绑定的后置处理器
ConfigurationPropertiesBindingPostProcessor.register(registry) {
// 是否包含"ConfigurationPropertiesBindingPostProcessor"的beanName
// "ConfigurationPropertiesBindingPostProcessor":ConfigurationPropertiesBindingPostProcessor
// 如果没有,将ConfigurationPropertiesBindingPostProcessor注册为Bean,处理属性绑定的Bean
if (!registry.containsBeanDefinition(BEAN_NAME)) {
GenericBeanDefinition definition = new GenericBeanDefinition();
definition.setBeanClass(ConfigurationPropertiesBindingPostProcessor.class);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(BEAN_NAME, definition);
}
ConfigurationPropertiesBinder.register(registry) {
// "org.springframework.boot.context.internalConfigurationPropertiesBinderFactory"
// 注册绑定工厂: ConfigurationPropertiesBinder.Factory
if (!registry.containsBeanDefinition(FACTORY_BEAN_NAME)) {
GenericBeanDefinition definition = new GenericBeanDefinition();
definition.setBeanClass(ConfigurationPropertiesBinder.Factory.class);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(ConfigurationPropertiesBinder.FACTORY_BEAN_NAME, definition);
}
// "org.springframework.boot.context.internalConfigurationPropertiesBinder"
// 注册内置的属性绑定器,类型为ConfigurationPropertiesBinder
// 使用上面的工厂的工厂方法来创建
if (!registry.containsBeanDefinition(BEAN_NAME)) {
GenericBeanDefinition definition = new GenericBeanDefinition();
definition.setBeanClass(ConfigurationPropertiesBinder.class);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
definition.setFactoryBeanName(FACTORY_BEAN_NAME);
definition.setFactoryMethodName("create");
registry.registerBeanDefinition(ConfigurationPropertiesBinder.BEAN_NAME, definition);
}
}
}
ConfigurationPropertiesBeanDefinitionValidator.register(registry) {
// "ConfigurationPropertiesBeanDefinitionValidator": ConfigurationPropertiesBeanDefinitionValidator
// 注册属性绑定到校验器,校验bean中是否存在@ConstructorBinding注解
// 只有在@ConfigurationProperties的类中,才可以在构造方法中添加@ConstructorBinding注解
if (!registry.containsBeanDefinition(BEAN_NAME)) {
GenericBeanDefinition definition = new GenericBeanDefinition();
definition.setBeanClass(ConfigurationPropertiesBeanDefinitionValidator.class);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(BEAN_NAME, definition);
}
// 注册绑定器,会注册绑定工厂和绑定器
// ConfigurationPropertiesBinder.Factory和ConfigurationPropertiesBinder
ConfigurationPropertiesBinder.register(registry);
}
ConfigurationBeanFactoryMetadata.register(registry) {
// "ConfigurationBeanFactoryMetadata"
// 配置BeanFactory工厂的元信息
if (!registry.containsBeanDefinition(BEAN_NAME)) {
GenericBeanDefinition definition = new GenericBeanDefinition();
definition.setBeanClass(ConfigurationBeanFactoryMetadata.class);
definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(ConfigurationBeanFactoryMetadata.BEAN_NAME, definition);
}
}
}
// 创建ConfigurationPropertiesBeanRegistrar对象,通常属性对象Bean的注册表
ConfigurationPropertiesBeanRegistrar beanRegistrar = new ConfigurationPropertiesBeanRegistrar(registry);
// 获取需要处理的注解类型
Set<Class<?>> types = getTypes(metadata) {
// 过滤EnableConfigurationProperties注解的value值
return metadata.getAnnotations()
.stream(EnableConfigurationProperties.class)
.flatMap((annotation) -> Arrays.stream(annotation.getClassArray(MergedAnnotation.VALUE)))
.filter((type) -> void.class != type).collect(Collectors.toSet());
}
// 注册属性配置对象Bean
types.forEach(beanRegistrar::register {
// 获取属性配置类中的ConfigurationProperties注解
MergedAnnotation<ConfigurationProperties> annotation = MergedAnnotations.from(type, SearchStrategy.TYPE_HIERARCHY).get(ConfigurationProperties.class);
// 注册
register(type, annotation) {
// 获取BeanName
String name = getName(type, annotation) {
// 获取注解中的prefix前缀
String prefix = annotation.isPresent() ? annotation.getString("prefix") : "";
// 使用前缀+"-"+属性配置类的名称拼接
// luck-luck.spring.boot.config.properties.LuckProperties
return (StringUtils.hasText(prefix) ? prefix + "-" + type.getName() : type.getName());
}
// 如果不包含,就将该配置类注册为Bean
if (!containsBeanDefinition(name)) {
registerBeanDefinition(name, type, annotation) {
// 创建BD
BeanDefinition bd = createBeanDefinition(beanName, type) {
// 如果属性配置类的构造方法中,存在ConstructorBinding注解
// 那么需要通过构造方法进行属性绑定
if (BindMethod.forType(type) == BindMethod.VALUE_OBJECT) {
// 创建特殊的BD,BD中存放已经创建好的对象
return new ConfigurationPropertiesValueObjectBeanDefinition(this.beanFactory, beanName, type) {
this.beanFactory =beanFactory;
this.beanName =beanName;
setBeanClass(beanClass);
// 提前创建bean对象给BD中,并且这个对象已经进行了构造属性的绑定
Object bean = this.createBean(){
ConfigurationPropertiesBean bean = ConfigurationPropertiesBean.forValueObject(getBeanClass(), this.beanName)
{
// 创建一个配置类属性的包装对象
ConfigurationPropertiesBean propertiesBean = create(beanName, null, beanClass, null)
{
// 查找@ConfigurationProperties注解
ConfigurationProperties annotation = findAnnotation(instance, type, factory, ConfigurationProperties.class);
// 再查找@Validated注解
Validated validated = findAnnotation(instance, type, factory, Validated.class);
// 保存这两个注解信息
Annotation[] annotations = (validated != null) ? new Annotation[]{annotation, validated} : new Annotation[]{annotation};
// 将属性配置类类型封装成ResolvableType
ResolvableType bindType = (factory != null) ? ResolvableType.forMethodReturnType(factory) : ResolvableType.forClass(type);
// 将配置类型和注解信息封装
Bindable<Object> bindTarget = Bindable.of(bindType).withAnnotations(annotations);
// 如果已经给定了配置类实例对象
if (instance != null) {
// 需要绑定的目标对象更新为指定的实例,封装到bindTarget中
bindTarget = bindTarget.withExistingValue(instance);
}
// 都保存到ConfigurationPropertiesBean配置属性Bean中
return new ConfigurationPropertiesBean(name, instance, annotation, bindTarget);
}
}
// 获取注册的ConfigurationPropertiesBinder绑定器Bean
ConfigurationPropertiesBinder binder = ConfigurationPropertiesBinder.get(this.beanFactory)
{
return beanFactory.getBean(BEAN_NAME, ConfigurationPropertiesBinder.class);
}
// 使用注册的绑定器进行绑定或者创建
// 详见下面,ConfigurationPropertiesBinder.bindOrCreate
return binder.bindOrCreate(bean);
}
Supplier<Object> supplier = () -> bean;
setInstanceSupplier(supplier);
}
}
// 不存在ConstructorBinding注解,直接创建配置类BD
GenericBeanDefinition definition = new GenericBeanDefinition();
definition.setBeanClass(type);
return definition;
}
this.registry.registerBeanDefinition(beanName, bd);
}
}
}
});
}
}
class ConfigurationPropertiesBindingPostProcessor {
public void afterPropertiesSet() throws Exception {
this.registry = (BeanDefinitionRegistry) this.applicationContext.getAutowireCapableBeanFactory();
// 初始化属性绑定器,在注册的时候会注入ConfigurationPropertiesBinder它
this.binder = ConfigurationPropertiesBinder.get(this.applicationContext) {
// org.springframework.boot.context.internalConfigurationPropertiesBinder
return beanFactory.getBean(BEAN_NAME, ConfigurationPropertiesBinder.class);
}
}
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
bind(ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName){
// 查找@ConfigurationProperties注解
ConfigurationProperties annotation = findAnnotation(instance, type, factory, ConfigurationProperties.class);
// 再查找@Validated注解
Validated validated = findAnnotation(instance, type, factory, Validated.class);
// 保存这两个注解信息
Annotation[] annotations = (validated != null) ? new Annotation[]{annotation, validated} : new Annotation[]{annotation};
// 将属性配置类类型封装成ResolvableType
ResolvableType bindType = (factory != null) ? ResolvableType.forMethodReturnType(factory) : ResolvableType.forClass(type);
// 将配置类型和注解信息封装
Bindable<Object> bindTarget = Bindable.of(bindType).withAnnotations(annotations);
// 如果已经给定了配置类实例对象
if (instance != null) {
// 需要绑定的目标对象更新为指定的实例,封装到bindTarget中
bindTarget = bindTarget.withExistingValue(instance);
}
// 将bean,name,注解,和bindTarget保存到ConfigurationPropertiesBean配置属性Bean中
return new ConfigurationPropertiesBean(name, instance, annotation, bindTarget);
}) {
// 使用绑定器进行绑定,详见ConfigurationPropertiesBinder.bind
// 在这里绑定的情况下,该ConfigurationProperties已经创建好了对象,就等着属性绑定了
// 最详细的可以看Spring,SpringBoot配置属性的绑定实现原理文章
this.binder.bind(bean)
}
return bean;
}
}
class ConfigurationPropertiesBinder {
// 和bindOrCreate几乎一样,不同的是,当属性为null的时候,当前方法不会创建默认的对象
BindResult<?> bind(ConfigurationPropertiesBean propertiesBean);
// 绑定对象,如果属性值不存在,给一个默认对象值
Object bindOrCreate(ConfigurationPropertiesBean propertiesBean) {
// 获取属性配置类实例对象
Bindable<?> target = propertiesBean.asBindTarget();
// 获取属性配置类中的注解信息,一个是@ConfigurationProperties,一个是@Validated
ConfigurationProperties annotation = propertiesBean.getAnnotation();
// 获取绑定的处理器,他是一个绑定过程中的生命周期回调类
BindHandler bindHandler = getBindHandler(target, annotation) {
List<Validator> validators = getValidators(target) {
// 校验器
List<Validator> validators = new ArrayList<>(3);
// 如果当前类设置校验器
if (this.configurationPropertiesValidator != null) {
// 保存
validators.add(this.configurationPropertiesValidator);
}
// 如果配置类中存在@Validated注解
if (this.jsr303Present && target.getAnnotation(Validated.class) != null) {
// 添加一个ConfigurationPropertiesJsr303Validator校验器器
validators.add(getJsr303Validator() {
this.jsr303Validator = new ConfigurationPropertiesJsr303Validator(this.applicationContext);
});
}
// 如果绑定器中设置了值,并且值为校验器类型
if (target.getValue() != null && target.getValue().get() instanceof Validator) {
// 将绑定器中的校验器也保存
validators.add((Validator) target.getValue().get());
}
// 返回可用的校验器
return validators;
}
// 默认绑定处理器IgnoreTopLevelConverterNotFoundBindHandler
BindHandler handler = new IgnoreTopLevelConverterNotFoundBindHandler();
// 如果ConfigurationProperties配置了
if (annotation.ignoreInvalidFields()) {
// 使用忽略错误的绑定器
handler = new IgnoreErrorsBindHandler(handler);
}
// 如果设置了ignoreUnknownFields为false
if (!annotation.ignoreUnknownFields()) {
// 添加一个过滤器
UnboundElementsSourceFilter filter = new UnboundElementsSourceFilter();
// 使用NoUnboundElementsBindHandler处理器
handler = new NoUnboundElementsBindHandler(handler, filter);
}
// 如果不存在校验器
if (!validators.isEmpty()) {
// 如果存在校验器,那么装饰一下原来的handler,处理之后还需要进行绑定校验
handler = new ValidationBindHandler(handler, validators.toArray(new Validator[0]));
}
// 从容器中获取ConfigurationPropertiesBindHandlerAdvisor类型的切面
for (ConfigurationPropertiesBindHandlerAdvisor advisor : getBindHandlerAdvisors() {
return this.applicationContext.getBeanProvider(ConfigurationPropertiesBindHandlerAdvisor.class).orderedStream().collect(Collectors.toList());
}){
// 应用切面
handler = advisor.apply(handler);
}
// 返回处理过后的handler
return handler;
}
// 创建属性绑定对象,该类专门用于绑定ConfigurationPropertySources中的属性
Binder binder = getBinder() {
if (this.binder == null) {
this.binder = new Binder(
// 系统环境中的所有属性
getConfigurationPropertySources(){
// 获取Spring容器中的所有配置信息
this.propertySources = new PropertySourcesDeducer(applicationContext).getPropertySources();
// 封装成SpringConfigurationPropertySources对象
return ConfigurationPropertySources.from(this.propertySources){
return new SpringConfigurationPropertySources(sources);
}
},
// 获取属性解析器
getPropertySourcesPlaceholdersResolver(),
// 类型转换器,从Spring容器中获取conversionService的Bean
getConversionService(),
// JDK的类型转换器初始器,从Spring中注册自定义的Editor
getPropertyEditorInitializer(), null,
// 配置属性类的构造方法提供者
ConfigurationPropertiesBindConstructorProvider.INSTANCE);
}
return this.binder;
}
// 使用绑定器进行属性绑定
// 最详细的可以看Spring,SpringBoot配置属性的绑定实现原理文章
return binder.bindOrCreate(annotation.prefix(), target, bindHandler) {
// 指定处理器,设置上下文
handler = (handler != null) ? handler : this.defaultBindHandler;
Context context = new Context();
// 绑定,原理,先绑定属性配置类对象,发现配置类对象又需要进行属性绑定,递归进行属性绑定,属性绑定全部完成
return bind(name, target, handler, context, false, create) {
// 清空上下的配置的属性信息
context.clearConfigurationProperty();
// 回调handler的start方法
// 替换目标对象
Bindable<T> replacementTarget = handler.onStart(name, target, context);
// 如果目标对象已经被替换为null
if (replacementTarget == null) {
// 就不需要属性绑定了,直接处理绑定结果
return handleBindResult(name, target, handler, context, null, create);
}
// 获取绑定的目标对象
target = replacementTarget;
// 绑定对象
Object bound = bindObject(name, target, handler, context, allowRecursiveBinding) {
// 从上下文中查找配置属性
ConfigurationProperty property = findProperty(name, context){
// 遍历所有存在上下文中的属性
// 获取Spring容器中的所有配置信息
// this.propertySources = new PropertySourcesDeducer(applicationContext).getPropertySources();
// 封装成SpringConfigurationPropertySources对象
// return ConfigurationPropertySources.from(this.propertySources){
// return new SpringConfigurationPropertySources(sources);
// }
for (ConfigurationPropertySource source : context.getSources(){
// 可以看上面创建Binder对象的时候,将整个Spring容器中的配置属性保存到这个变量中
return Binder.this.sources;
}) {
// 根据名称从所有环境属性中,获取对应的属性
// 因此,对象中的属性是能从appplication.yml中获取对属性
ConfigurationProperty property = source.getConfigurationProperty(name);
if (property != null) {
return property;
}
}
return null;
}
// 如果解析到的属性类型,如果是Map,Collection,Array的话,单独处理
AggregateBinder<?> aggregateBinder = getAggregateBinder(target, context);
// 如果不为空,表示当前解析的属性配置类是多个元素
if (aggregateBinder != null) {
// 绑定聚合的属性
return bindAggregate(name, target, handler, context, aggregateBinder);
}
// 如果属性类型不是集合类,并且Spring的所有配置中存在该属性,我们就可以直接进行属性绑定
if (property != null) {
// 进行属性绑定,这里
return bindProperty(target, context, property) {
// 保存正在绑定的属性
context.setConfigurationProperty(property);
// 获取属性值
Object result = property.getValue();
// 解析属性值的占位符
result = this.placeholdersResolver.resolvePlaceholders(result);
// 使用类型转换器进行转换
result = context.getConverter().convert(result, target);
// 返回属性结果
return result;
}
}
// 将值绑定到对象上
return bindDataObject(name, target, handler, context, allowRecursiveBinding) {
// 创建一个对象属性的绑定器,当需要绑定的时候,回调bind方法,该回调bind方法就是上面bindOrCreate调用的bind方法,这里是在递归绑定
// 先绑定属性对应的类,在绑定属性类中的属性
DataObjectPropertyBinder propertyBinder = (propertyName, propertyTarget) -> bind(name.append(propertyName),propertyTarget, handler, context, false, false);
return context.withDataObject(type, () -> {
// 遍历属性绑定器
// ValueObjectBinder valueObjectBinder = new ValueObjectBinder(constructorProvider);
// JavaBeanBinder javaBeanBinder = JavaBeanBinder.INSTANCE;
// 一个是JavaBeanBinder,一个是简单ValueObjectBinder
// this.dataObjectBinders = Collections.unmodifiableList(Arrays.asList(valueObjectBinder, javaBeanBinder));
for (DataObjectBinder dataObjectBinder : this.dataObjectBinders) {
// 看一下那个绑定器可以绑定成功,绑定成功,返回绑定好的配置类对象
// 这个方法是一个抽象方法,有对构造方法进行绑定的对象ValueObjectBinder,还有对属性进行绑定的JavaBeanBinder
Object instance = dataObjectBinder.bind(name, target, context, propertyBinder) {
// 构造方法绑定的实现
ValueObjectBinder.bind(){
// 获取需要绑定的属性对象,这里就是处理需要构造注入的参数,如果不需要构造注入,就为空
ValueObject<T> valueObject = ValueObject.get(target, this.constructorProvider, context)
{
// 找当前类需要绑定的构造方法
Constructor<?> bindConstructor = constructorProvider.getBindConstructor(bindable, context.isNestedConstructorBinding())
{
// 找存在@ConstructorBinding的构造方法
Constructor<?> constructor = findConstructorBindingAnnotatedConstructor(type)
{
for (Constructor<?> candidate : candidates) {
if (MergedAnnotations.from(candidate).isPresent(ConstructorBinding.class)) {
constructor = candidate;
}
}
return constructor;
}
// 如果没找到
if (constructor == null && (isConstructorBindingAnnotatedType(type) || isNestedConstructorBinding)) {
// 如果没有@ConstructorBinding注解,还要处理只有一个构造方法并且有参数的场景
constructor = deduceBindConstructor(type) {
// 获取所有的构造方法
Constructor<?>[] constructors = type.getDeclaredConstructors();
// 如果只有一个,并且还有参数
if (constructors.length == 1 && constructors[0].getParameterCount() > 0) {
// 返回唯一的一个构造方法
return constructors[0];
}
// 否返回null,也就是不需要构造绑定,只需要创建默认对象就行
return null;
}
}
return constructor;
}
}
// 如果需要绑定的对象构造方法不存在@ConstructorBinding注解,并且只有默认的构造函数,就不需要进行构造注入属性
if (valueObject == null) {
return null;
}
// 保存构造方法需要绑定的属性类型
context.pushConstructorBoundTypes(target.getType().resolve());
// 获取需要绑定的属性的构造方法参数
List<ConstructorParameter> parameters = valueObject.getConstructorParameters();
List<Object> args = new ArrayList<>(parameters.size());
boolean bound = false;
// 遍历所有的构造参数
for (ConstructorParameter parameter : parameters) {
// 回调DataObjectPropertyBinder封装的bind方法,实际上就是绑定属性,递归绑定
Object arg = parameter.bind(propertyBinder) {
// DataObjectPropertyBinder propertyBinder = (propertyName, propertyTarget) -> bind(name.append(propertyName),propertyTarget, handler, context, false, false);
return propertyBinder.bindProperty(this.name, Bindable.of(this.type).withAnnotations(this.annotations));
}
// 是否绑定成功
bound = bound || arg != null;
// 如果没有参数值,获取参数的默认值
arg = (arg != null) ? arg : parameter.getDefaultValue(context.getConverter());
// 保存处理好的参数值
args.add(arg);
}
// 清空配置属性
context.clearConfigurationProperty();
// 将正在绑定的属性出栈
context.popConstructorBoundTypes();
// 通过保存好的参数实例化,如果没有构造参数,就可以直接使用默认的构造参数,如果有构造参数,args就不会为空
return bound ? valueObject.instantiate(args) : null;
}
// 属性绑定的实现
JavaBeanBinder.bind(){
// 是否找到了可以绑定的属性
boolean hasKnownBindableProperties = target.getValue() != null && hasKnownBindableProperties(name, context);
// 获取操作属性的Bean对象
Bean<T> bean = Bean.get(target, hasKnownBindableProperties){
// 获取绑定的类型
ResolvableType type = bindable.getType();
// 绑定类型的class
Class<?> resolvedType = type.resolve(Object.class);
// 获取绑定的对象值
Supplier<T> value = bindable.getValue();
T instance = null;
// 如果有可以绑定的属性,并且对象也不为空
if (canCallGetValue && value != null) {
// 获取到实例对象
instance = value.get();
// 获取到实例对象的Class类型
resolvedType = (instance != null) ? instance.getClass() : resolvedType;
}
// 如果绑定的实例对象为空,并且不可以实例化就不处理
if (instance == null && !isInstantiable(resolvedType)) {
return null;
}
// 获取绑定类型的缓存
Bean<?> bean = Bean.cached;
// 如果没有被缓存,创建Bean对象
if (bean == null || !bean.isOfType(type, resolvedType)) {
bean = new Bean<>(type, resolvedType){
this.type = type;
this.resolvedType = resolvedType;
// 找到类中所有的方法和字段进行绑定
addProperties(resolvedType){
while (type != null && !Object.class.equals(type)) {
// 所有方法
Method[] declaredMethods = type.getDeclaredMethods();
// 所有字段
Field[] declaredFields = type.getDeclaredFields();
// 添加属性
addProperties(declaredMethods, declaredFields){
for (int i = 0; i < declaredMethods.length; i++) {
if (!isCandidate(declaredMethods[i]){
int modifiers = method.getModifiers();
// 私有的,Protected,Abstract,Static,Object的方法,Class的方法,代理方法都不满足条件
return !Modifier.isPrivate(modifiers) && !Modifier.isProtected(modifiers) && !Modifier.isAbstract(modifiers)
&& !Modifier.isStatic(modifiers) && !Object.class.equals(method.getDeclaringClass())
&& !Class.class.equals(method.getDeclaringClass()) && method.getName().indexOf('$') == -1;
}) {
// 将该方法过滤
declaredMethods[i] = null;
}
}
// 找get/is方法
for (Method method : declaredMethods) {
addMethodIfPossible(method, "get", 0, BeanProperty::addGetter);
addMethodIfPossible(method, "is", 0, BeanProperty::addGetter);
}
// 找set方法
for (Method method : declaredMethods) {
addMethodIfPossible(method, "set", 1, BeanProperty::addSetter);
}
// 添加字段
for (Field field : declaredFields) {
addField(field);
}
}
// 继续获取父类的属性
type = type.getSuperclass();
}
}
}
// 缓存创建好的Bean对象
cached = bean;
}
return (Bean<T>) bean;
}
// 如果类型不匹配,不处理
if (bean == null) {
return null;
}
// 获取
BeanSupplier<T> beanSupplier = bean.getSupplier(target){
return new BeanSupplier<>(() -> {
T instance = null;
// 如果存在实例对象Supplier
if (target.getValue() != null) {
// 获取Supplier的实例对象的值
instance = target.getValue().get();
}
// 如果没有设置实例对象
if (instance == null) {
// 根据绑定类型实例化类型对象
instance = (T) BeanUtils.instantiateClass(this.resolvedType);
}
// 返回绑定的属性的实例
return instance;
});
}
// 属性绑定
boolean bound = bind(propertyBinder, bean, beanSupplier){
boolean bound = false;
// 遍历所有的属性,一一绑定
for (BeanProperty beanProperty : bean.getProperties().values()) {
bound |= bind(beanSupplier, propertyBinder, beanProperty){
// 获取属性名和属性类型
String propertyName = property.getName();
ResolvableType type = property.getType();
// 获取属性的get方法
Supplier<Object> value = property.getValue(beanSupplier);
// 获取属性注解
Annotation[] annotations = property.getAnnotations();
// 递归属性绑定,上面有讲解,返回需要绑定属性的值
Object bound = propertyBinder.bindProperty(propertyName,Bindable.of(type).withSuppliedValue(value).withAnnotations(annotations));
// 如果没有获取到需要绑定的值
if (bound == null) {
// 绑定失败
return false;
}
// 获取到需要绑定的值,并且存在set方法
if (property.isSettable()) {
// 调用set方法,设置属性值
property.setValue(beanSupplier, bound);
}
// 如果属性没有set方法,抛出异常
else if (value == null || !bound.equals(value.get())) {
throw new IllegalStateException("No setter found for property: " + property.getName());
}
return true;
}
}
return bound;
}
// 如果绑定成功,返回绑定的对象,如果没有绑定成功,返回null
return (bound ? beanSupplier.get() : null);
}
};
// 返回实例化好的属性对象
if (instance != null) {
return instance;
}
}
});
}
}
return handleBindResult(name, target, handler, context, bound, create) {
// 解析到了属性值
if (result != null) {
// 回调处理器的success方法
result = handler.onSuccess(name, target, context, result);
// 使用类型转换器进行类型转换
result = context.getConverter().convert(result, target);
}
// 如果没有解析到值,并且指定需要创建
if (result == null && create) {
// 使用所有的绑定器进行创建属性对应的默认对象
result = create(target, context) {
// ValueObjectBinder valueObjectBinder = new ValueObjectBinder(constructorProvider);
// JavaBeanBinder javaBeanBinder = JavaBeanBinder.INSTANCE;
// 一个是JavaBeanBinder,一个是简单ValueObjectBinder
// this.dataObjectBinders = Collections.unmodifiableList(Arrays.asList(valueObjectBinder, javaBeanBinder));
for (DataObjectBinder dataObjectBinder : this.dataObjectBinders) {
// 创建属性配置类实例
Object instance = dataObjectBinder.create(target, context){
// 判断属性是否需要构造注入
ValueObject<T> valueObject = ValueObject.get(target, this.constructorProvider, context);
// 不需要,就不处理了
if (valueObject == null) {
return null;
}
// 如果需要,就创建构造函数需要的类型的默认值
List<ConstructorParameter> parameters = valueObject.getConstructorParameters();
List<Object> args = new ArrayList<>(parameters.size());
// 保存构造参数的默认值
for (ConstructorParameter parameter : parameters) {
args.add(parameter.getDefaultValue(context.getConverter()));
}
// 实例化对象
return valueObject.instantiate(args);
}
// 返回处理好的属性对象
if (instance != null) {
return instance;
}
}
}
// 回调handelr的create方法
result = handler.onCreate(name, target, context, result);
// 将创建的值进行类型转换
result = context.getConverter().convert(result, target);
}
// 回调handler的finish方法
handler.onFinish(name, target, context, result){
// 绑定之后,进行属性校验
validate(name, target, context, result){
// 需要校验的目标对象
Object validationTarget = getValidationTarget(target, context, result);
// 获取校验的目标类型
Class<?> validationType = target.getBoxedType().resolve();
if (validationTarget != null) {
// 校验
validateAndPush(name, validationTarget, validationType){
// 校验结果
ValidationResult result = null;
// 遍历所有的校验器
for (Validator validator : this.validators) {
// 看一下那个校验器支持
if (validator.supports(type)) {
// 封装成ValidationResult对象
result = (result != null) ? result : new ValidationResult(name, target);
// 使用校验器进行校验,封装校验结果到result中
validator.validate(target, result);
}
}
// 如果校验成功,并且有错误
if (result != null && result.hasErrors()) {
// 保存异常信息
this.exceptions.push(new BindValidationException(result.getValidationErrors()));
}
}
}
// 如果深度为0,表示全部校验完成,并且有错误的话
if (context.getDepth() == 0 && !this.exceptions.isEmpty()) {
// 抛出异常信息
throw this.exceptions.pop();
}
}
super.onFinish(name, target, context, result);
}
// 其他情况,直接进行类型转换返回
return context.getConverter().convert(result, target);
}
}
}
}
}
class ConfigurationPropertiesBeanDefinitionValidator {
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 实际上就是校验这些Bean中的构造方法中是否存在@ConstructorBinding注解
// 如果存在@ConstructorBinding注解,就要报错
// 只有在@ConfigurationProperties的类中,才可以在构造方法中添加@ConstructorBinding注解
// 确保后面的属性绑定是正确的
for (String beanName : beanFactory.getBeanDefinitionNames()) {
// 如果不是单例,或者BD不是ConfigurationPropertiesValueObjectBeanDefinition类型
if (!(beanFactory.containsSingleton(beanName) || isValueObjectBeanDefinition(beanFactory, beanName))) {
// 开始校验
validate(beanFactory, beanName) {
// 实际上就是校验这些Bean中的构造方法中是否存在@ConstructorBinding注解
// 如果存在@ConstructorBinding注解,就要报错
// 只有在@ConfigurationProperties的类中,才可以在构造方法中添加@ConstructorBinding注解,而上面这种情况已经过滤了,不会进来
Class<?> beanClass = beanFactory.getType(beanName, false);
if (beanClass != null && BindMethod.forType(beanClass) == BindMethod.VALUE_OBJECT) {
throw new BeanCreationException(beanName, "@EnableConfigurationProperties or @ConfigurationPropertiesScan must be used to add ");
}
}
}
}
}
}
SpringBoot中@EnableConfigurationProperties和ConfigurationProperties运行原理
于 2024-03-26 19:40:49 首次发布