# @ConfigurationProperties

# 使用示例

@ConfigurationProperties注解结合@Component在类上使用

@Component
@ConfigurationProperties("rocketmq")
@Data
public class RocketMQProperties {

    private String accessKey;
    private String secretKey;
    private String nameSrvAddr;
    private String topic;
    private String groupId;
    private String tag;
    private String orderTopic;
    private String orderGroupId;
    private String orderTag;

    public Properties getMqProperties() {
        Properties properties = new Properties();
        properties.setProperty(PropertyKeyConst.AccessKey, this.accessKey);
        properties.setProperty(PropertyKeyConst.SecretKey, this.secretKey);
        properties.setProperty(PropertyKeyConst.NAMESRV_ADDR, this.nameSrvAddr);
        return properties;
    }

    public Properties getMqConsumerProperties() {
        //配置文件
        Properties properties = this.getMqProperties();
        properties.setProperty(PropertyKeyConst.GROUP_ID, this.getGroupId());
        //将消费者线程数固定为20个 20为默认值
        properties.setProperty(PropertyKeyConst.ConsumeThreadNums, "20");
        return properties;
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

@ConfigurationProperties注解结合@Bean在方法上使用

    @Bean
    @ConfigurationProperties("rocketmq")
    public RocketMQProperties rocketMQProperties() {
        return new RocketMQProperties();
    }
1
2
3
4
5

@ConfigurationProperties注解结合@EnableConfigurationProperties在类上使用,这个时候不需要使用@Component相关注解了

@EnableConfigurationProperties({RocketMQProperties.class})
1

属性

rocketmq.access-key = 您的access-key
rocketmq.secret-key = 您的secret-key
# 设置 TCP 接入域名,进入控制台的实例管理页面的“获取接入点信息”区域查看
rocketmq.name-srv-addr = http://onsaddr.cn-hangzhou.mq-internal.aliyuncs.com:8080
# 您在控制台创建的 Group ID
rocketmq.group-id = GID_BRAIN_TR_TOOL_FAT
rocketmq.topic = BRAIN_TR_TOOL_FAT
1
2
3
4
5
6
7

# @ConfigurationProperties vs. @Value

The @Value annotation is a core container feature, and it does not provide the same features as type-safe configuration properties. The following table summarizes the features that are supported by @ConfigurationProperties and @Value:

特征 @ConfigurationProperties @Value
宽松的绑定 (opens new window) Yes No
元数据支持 (opens new window) Yes No
SpEL 表达式 No Yes

If you define a set of configuration keys for your own components, we recommend you group them in a POJO annotated with @ConfigurationProperties. You should also be aware that, since @Value does not support relaxed binding, it is not a good candidate if you need to provide the value by using environment variables.

Finally, while you can write a SpEL expression in @Value, such expressions are not processed from application property files.

# 实现原理

首先@ConfigurationProperties需要和@Bean或者@Component等只要能生成spring bean的注解结合起来使用

这样当其他类注入Spring容器时,在bean加载过程中,会调用AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization,因此会触发ConfigurationPropertiesBindingPostProcessor#postProcessBeforeInitialization的调用。

涉及到的相关实现类和方法如下:

org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.java

    // bean初始化方法调用前被调用
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		ConfigurationProperties annotation = getAnnotation(bean, beanName, ConfigurationProperties.class);
		if (annotation != null) {
			bind(bean, beanName, annotation);
		}
		return bean;
	}

	private void bind(Object bean, String beanName, ConfigurationProperties annotation) {
		ResolvableType type = getBeanType(bean, beanName);
		Validated validated = getAnnotation(bean, beanName, Validated.class);
		Annotation[] annotations = (validated != null) ? new Annotation[] { annotation, validated }
				: new Annotation[] { annotation };
		Bindable<?> target = Bindable.of(type).withExistingValue(bean).withAnnotations(annotations);
		try {
			this.configurationPropertiesBinder.bind(target);
		}
		catch (Exception ex) {
			throw new ConfigurationPropertiesBindException(beanName, bean, annotation, ex);
		}
	}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

org.springframework.boot.context.properties.ConfigurationPropertiesBinder.java

	public void bind(Bindable<?> target) {
		ConfigurationProperties annotation = target.getAnnotation(ConfigurationProperties.class);
		Assert.state(annotation != null, () -> "Missing @ConfigurationProperties on " + target);
		List<Validator> validators = getValidators(target);
		BindHandler bindHandler = getBindHandler(annotation, validators);
		getBinder().bind(annotation.prefix(), target, bindHandler);
	}
1
2
3
4
5
6
7

最后调用org.springframework.boot.context.properties.bind.Binder.java中的方法来完成绑定。


参考文档

Last Updated: 3 years ago