springboot @ConfigurationProperties注入属性流程
一、編寫(xiě)實(shí)例,只要加上ConfigurationProperties注解,就會(huì)從當(dāng)前springboot的Environment中讀取配置屬笥。Environment包括bootStrap,application,application_dev等。
@Data @Configuration @ConfigurationProperties(prefix = "redisson") public class RedissonProperties {private int timeout = 3000;private String address;private String password;private int database = 0;private int connectionPoolSize = 64;private int connectionMinimumIdleSize=10;private int slaveConnectionPoolSize = 250;private int masterConnectionPoolSize = 250;private String[] sentinelAddresses;private String masterName; }二、注入流程
1.在SPRING容器實(shí)例化BEAN對(duì)象后,會(huì)觸發(fā)
ConfigurationPropertiesBindingPostProcessor.postProcessBeforeInitialization方法,進(jìn)行屬性值注入。這種跟@resource的依賴注入流程機(jī)制是一樣的,都是實(shí)現(xiàn)了BeanPostProcessor的后置處理器,進(jìn)行屬性的修改,或者對(duì)象的代理封裝轉(zhuǎn)換等。 org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {bind(ConfigurationPropertiesBean.get(this.applicationContext, bean, beanName));return bean;}?2.隨后會(huì)調(diào)用ConfigurationPropertiesBean.create方法,判斷BEAN類上是否有ConfigurationProperties注解,有才進(jìn)行配置文件的屬性注入。
private static ConfigurationPropertiesBean create(String name, Object instance, Class<?> type, Method factory) {ConfigurationProperties annotation = findAnnotation(instance, type, factory, ConfigurationProperties.class);if (annotation == null) {return null;}Validated validated = findAnnotation(instance, type, factory, Validated.class);Annotation[] annotations = (validated != null) ? new Annotation[] { annotation, validated }: new Annotation[] { annotation };ResolvableType bindType = (factory != null) ? ResolvableType.forMethodReturnType(factory): ResolvableType.forClass(type);Bindable<Object> bindTarget = Bindable.of(bindType).withAnnotations(annotations);if (instance != null) {bindTarget = bindTarget.withExistingValue(instance);}return new ConfigurationPropertiesBean(name, instance, annotation, bindTarget);}?
3.真正讀取配置文件屬性并綁定設(shè)置到BEAN對(duì)象屬性中是由?
ConfigurationPropertiesBinder.bind方法完成。 BindResult<?> bind(ConfigurationPropertiesBean propertiesBean) {Bindable<?> target = propertiesBean.asBindTarget();ConfigurationProperties annotation = propertiesBean.getAnnotation();BindHandler bindHandler = getBindHandler(target, annotation);return getBinder().bind(annotation.prefix(), target, bindHandler);}4.隨后會(huì)調(diào)用org.springframework.boot.context.properties.bind.binder.bindDataObject 進(jìn)行數(shù)據(jù)對(duì)
象綁定。
private Object bindDataObject(ConfigurationPropertyName name, Bindable<?> target, BindHandler handler,Context context, boolean allowRecursiveBinding) {if (isUnbindableBean(name, target, context)) {return null;}Class<?> type = target.getType().resolve(Object.class);if (!allowRecursiveBinding && context.isBindingDataObject(type)) {return null;}DataObjectPropertyBinder propertyBinder = (propertyName, propertyTarget) -> bind(name.append(propertyName),propertyTarget, handler, context, false, false);return context.withDataObject(type, () -> {for (DataObjectBinder dataObjectBinder : this.dataObjectBinders) {Object instance = dataObjectBinder.bind(name, target, context, propertyBinder);if (instance != null) {return instance;}}return null;});}5.其中有個(gè)JAVA數(shù)據(jù)對(duì)象,會(huì)遍歷當(dāng)前對(duì)象的所有屬性,逐個(gè)屬性進(jìn)行讀取配置,進(jìn)行綁定。
org.springframework.boot.context.properties.bind.JavaBeanBinder private <T> boolean bind(DataObjectPropertyBinder propertyBinder, Bean<T> bean, BeanSupplier<T> beanSupplier,Context context) {boolean bound = false;for (BeanProperty beanProperty : bean.getProperties().values()) {bound |= bind(beanSupplier, propertyBinder, beanProperty);context.clearConfigurationProperty();}return bound;}6.最終會(huì)調(diào)用Binder.findProperty進(jìn)行屬性查找。這里面的context.getSource就是springboot初始化時(shí)加載的各類資源配置屬性對(duì)象列表。包括系統(tǒng)環(huán)境變量,配置文件,JVM參數(shù)等。
private ConfigurationProperty findProperty(ConfigurationPropertyName name, Context context) {if (name.isEmpty()) {return null;}for (ConfigurationPropertySource source : context.getSources()) {ConfigurationProperty property = source.getConfigurationProperty(name);if (property != null) {return property;}}return null;}7.綁定完的屬性注入如下,可以看到配置的屬性已經(jīng)注入進(jìn)去。
總結(jié)
以上是生活随笔為你收集整理的springboot @ConfigurationProperties注入属性流程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: spring mvc @ModelAtt
- 下一篇: springboot 读取applica