SpringBoot中@EnableConfigurationProperties和ConfigurationProperties运行原理

@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 ");
                    }
                }
            }
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值