Springboot注解@EnableConfigurationProperties、@ConfigurationProperties、@ConfigurationPropertiesScan区别

在SpringBoot工程中,我们常常需要将一些特定前缀的配置项绑定到一个配置类上。这时候我们就可以使用@EnableConfigurationProperties、@ConfigurationProperties注解来实现。在SpringBoot2.2.0中还添加@ConfigurationPropertiesScan注解来帮助我们简化将配置类注册成一个Bean。下面主要讲解这三个注解的使用和源码实现。

现在我有如下的propertoes(yml)文件,里面添加了一些配置信息

#绑定到配置类 com.example.demo.config.MyBatisProperties
mybatis.basePackage= com.example.web.mapper
mybatis.mapperLocations= classpath*:mapper/*.xml
mybatis.typeAliasesPackage= com.example.web.model
mybatis.defaultStatementTimeoutInSecond= 5
mybatis.mapUnderscoreToCamelCase= false

#绑定到配置项类 com.example.demo.config.ShardingProperties
sharding.defaultDSIndex= 0
sharding.dataSources[0].driverClassName= com.mysql.jdbc.Driver
sharding.dataSources[0].jdbcUrl= jdbc:mysql://localhost:3306/lwl_db0?useSSL=false&characterEncoding=utf8
sharding.dataSources[0].username= root
sharding.dataSources[0].password= 123456
sharding.dataSources[0].readOnly= false

@ConfigurationProperties

@ConfigurationProperties注解其实只是指定了配置类中属性所对应的前缀,当一个配置类仅仅被@ConfigurationProperties标记时,配置项的值是不会被绑定其属性的,也不会将其注册为Bean,需要同时使用@Component注解或是@Component子类注解(例如@Configuration)。

@EnableConfigurationProperties

@EnableConfigurationProperties(value={xxx.calss})指定具体的配置类来绑定属性值。主要有两个作用:

  1. 注册后置处理器ConfigurationPropertiesBindingPostProcessor,用于在Bean被初始化时,给Bean中的属性绑定属性值。这也是为什么第一种方式使用@ConfigurationProperties需要使用@Component注解的原因,否则其不是Bean,无法被Spring处理的后置处理器处理则无法绑定属性值。
  2. 将一个被标记@ConfigurationProperties的配置类注册为Spring的一个Bean,没有被标记@ConfigurationProperties注解的类不能做为@EnableConfigurationProperties的参数,否则抛出异常。仅仅使用@ConfigurationProperties也不会将这个类注册为一个Bean

@ConfigurationPropertiesScan

在SpringBoot2.2之后,如果想让一个仅有@ConfigurationProperties注解的配置类被注册为bean,可以通过@ConfigurationPropertiesScan注解开启。则不再需要配合@Component一起使用。
实现原理

  1. 这个注解是使用@Import注解向Spring容器导入org.springframework.boot.context.properties.ConfigurationPropertiesScanRegistrar
  2. 该类实现了ImportBeanDefinitionRegistrar接口,Spring在启动过程中会回调该接口的方法。
  3. ConfigurationPropertiesScanRegistrar会通过包扫描,扫描被@ConfigurationProperties标记的类
  4. 遍历扫描到的标有@ConfigurationProperties类,排除标有@Component类,避免配置类被重复注册,则将其注册为Bean,beanName为prefix+配置类全类名。
  5. 当配置类注册为 bean 后,@EnableConfigurationProperties注册的后置处理器则可以对其进行属性绑定.

例子

例子一:

例子

例子二:

对于springboot来说都会有这么一个类ServerProperties(读取启动的yml文件)
假如你直接@Autowired直接注入,得到的是一个空(相当于new了一个存新的),需要使用@EnableConfigurationProperties来读取你在yml中的配置

@EnableConfigurationProperties({ServerProperties.class})
@Component
public class PortRuleCompiler implements CommonServiceConstant{
	@Autowired
	private RequestMappingHandlerMapping mapping;



	private final String contextPath;
	/** Spring应用上下文环境 */
	@Autowired
    private ConfigurableListableBeanFactory beanFactory;
	@SuppressWarnings("unused")
	@Autowired 
	private RedisInfo redisInfo;
	public PortRuleCompiler(ServerProperties serverProperties) {
		/**
		 * spring-boot 旧版本(如1.5.9RELEASE),context-path定义在server.前缀下,
		 * 高版本定义在server.servlet.前缀下,
		 * 从 ServerProperties 实例获取 context-path,兼容spring-boot不同的版本,
		 * 先尝试获取 contextPath字段,如果失败则尝试获取嵌入字段 servlet.contextPath,
		 * 如果都失败则默认为空字符串,即没有定义context-path
		 */
		String contextPath;
		BeanUtilsBean beanUtils = BeanUtilsBean.getInstance();
		try {
			contextPath = firstNonNull(beanUtils.getProperty(serverProperties, "contextPath"),"");
		}catch (Exception e){
			try {
				contextPath = firstNonNull(beanUtils.getProperty(serverProperties, "servlet.contextPath"),"");
			}catch (Exception e1){
				contextPath = "";
			}
		}
		this.contextPath = contextPath;
	}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LC超人在良家

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值