Spring中读取配置属性的方式和SpringBoot自动配置重要特性

一、引言

SpringBoot的自动配置中,有两个分量很重的注解 @ConfigurationProperties@EnableConfigurationProperties。这两个注解能干嘛呢?它们的原理又是什么呢?下面本文就来学习一下。

在学习@ConfigurationProperties之前,先来回想一下在Spring中读取配置属性的方式有哪些?是不是立刻就会想到@Value注解?对,就是这个注解。

下面对@Value@PropertySource@ConfigurationProperties等相关注解进行学习介绍。

二、属性赋值相关注解

1、@Value

@Value注解非常有用,它的用法也非常多,但这里只介绍一种情况,也是本人在开发中最常用的情况,至于其他使用方式,例如:普通字符串的注入和表达式的注入意义不是很大,此处不做过多介绍。

@Value注解最常用的一种方式,就是将配置文件中自定义的属性值注入到特定属性中,下面直接上代码。
配置文件测试类及结果
解释一下:application.properties配置文件中,自定义了一个属性person.name,通过@Value注解,就可以将这个配置文件中自定义的值映射到代码中的属性上。

注意:此处@Value的值还可以从系统变量中取值。

上面这种方式,就是本人在日常开发中最常用的方式。那么什么情况下会用到这个@Value注解呢?可配置属性。例如,现在有个功能是要接受客户端上传上来的文件,存放文件的目录要求可以动态配置,不能在代码中写死,是不是想到这个注解了?

这里需要注意的是:在使用${ key }去获取值时,如果 key 找不到,启动会失败,这样是不对的,我们不能因为一个属性没有配置而让项目无法启动。所以,我们可以给它一个默认值,就如下面的配置,如果person.name拿不到值,就用scorpios作为默认值。

    @Value("${person.name:scorpios}")
    String name;
2、@PropertySource:加载配置属性源

@PropertySource注解也是非常非常的强大,通过@PropertySource注解可以把配置文件加载进来,然后使用@Value获取其中的属性值。

在上面的例子,@Value注解获取属性值是从application.properties配置文件中获取的。如果现在我们不在配置文件中配置这些属性,而是单独放在一个文件中,怎么办呢?看下面代码:

@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {

    @Value("${jdbc.name}")
    private String name;

    @Value("${jdbc.password}")
    private String password;

    public String print(){
        return name + "-" + password;
    }

在这里插入图片描述在这里插入图片描述
是不是不用讲就已经明白@PropertySource的使用了?哈哈~~~~~
下面来对@PropertySource各属性介绍:

  1. value:数组。用于指定配置文件的位置。支持classpath:file:等前缀, Spring发现是classpath开头的,因此最终使用的是Resource的子类ClassPathResource。如果是file开头的,则最终使用的类是FileSystemResource

  2. ignoreResourceNotFound:默认值false。表示如果没有找到文件就报错,若改为true就不报错。建议保留false。

  3. encoding:加载进来的编码。一般不用设置,可以设置为UTF-8等等

  4. factory:默认的值为DefaultPropertySourceFactory.class

需要注意的是PropertySourceFactory的加载时机早于SpringIOC容器,因此实现上不能依赖于Spring的IOC。(能理解最好,要不然仅当了解就好)
3、@ConfigurationProperties

注意:上面两个注解都是Spring Framwork提供的功能。而@ConfigurationPropertiesSpring Boot提供的。包括@EnableConfigurationProperties也是Spring Boot才有的。它在自动化配置中起到了非常关键的作用。

@ConfigurationProperties的作用就是,它可以把配置文件中的配置信息自动封装成对应的实体类,来看一下例子。(☆☆☆☆☆)

// application.properties配置文件中的配置属性

test.people.name=scorpios
test.people.age=30
test.people.address[0]=上海
test.people.address[1]=南京
test.people.address[2]=苏州
// 要封装的实体类
@Component // 注意一下这个注解!!!!
@ConfigurationProperties(prefix = "test.people")
public class People {
    private String name;
    private Integer age;
    private List<String> address;
	// setter / getter / toString 方法省略
}

在这里插入图片描述
同样的问题,如果不在application.properties配置文件中指定这些属性值,而是需要额外指定配置文件,就需要结合@PropertySource注解使用,结果依然可以。

@Component // 注意一下这个注解!!!!
@ConfigurationProperties(prefix = "test.people")
@PropertySource(value = {"classpath:people.properties"})
public class People {

    private String name;
    private Integer age;
    private List<String> address;
    }
在读Spring源码时,关注ConfigurationPropertiesBindingPostProcessor后置处理器,它会对标注@ConfigurationProperties注解的Bean进行属性值配置。

上面的代码中,在使用@ConfigurationProperties注解时,特意强调了一下要加@Component注解。如果不加@Component这个注解,在启动程序时会报错。这能说明什么问题呢?

这能说明:@ConfigurationProperties注解主要作用是把properties配置文件赋值给SpringIOC容器中的Bean的,这个注解作用的前提条件就是这个实体类必须已经转化为了Bean,并且已经存在与SpingIOC容器中。

但是!!!当我们在看SpringBoot自动配置源码时,并没有看到属性类上面加了这个@Component注解!!!(不信的话,可以去查看各个自动配置类需要用到的对应***Properties类,这里我只放两个类),这是为什么呢?这就涉及到SpringBoot的自动装配原理了。
在这里插入图片描述
在这里插入图片描述
好了,下面要引入@EnableConfigurationProperties注解,这个注解的作用是让@ConfigurationProperties注解生效。什么意思呢?

就是说如果我们在需要映射的实体类上只标注了@ConfigurationProperties注解,但是这个实体类并没有转化为Bean存在于SpringIOC容器中,这个注解是没有用的(会报错),也就是说属性绑定会失败。(能理解此处的Bean的意思么?)

这里先说一下,用@EnableConfigurationProperties注解会将对应的实体类转为Bean加入到SpringIOC容器中,如下所示。至于为什么?且听下回分解。
在这里插入图片描述

终于讲完啦。。。。。理解了么?

三、小结

简单总结一下

1、@ConfigurationProperties注解 是将application配置文件的某类名下所有的属性值,自动封装到实体类中。这个注解作用的前提条件就是,实体类已经转化为Bean存在于SpringIOC容器中。

2、@EnableConfigurationProperties注解的作用是让@ConfigurationProperties注解生效。也就是让@ConfigurationProperties注解绑定的实体类转为为Bean交给SpingIOC容器管理。从而让@ConfigurationProperties注解生效。

3、@Value 是将application配置文件中,所需要的某个属性值,封装到Java代码中以供使用。


补充

@ImportResource注解

此注解的作用是导入Spring的配置文件,让配置文件里面的内容生效。此注解常常在老的Spring项目SpringBoot项目迁移过程中使用。因为 Spring Boot 里面根本就没有Spring的配置文件,我们自己编写的配置文件,SpringBoot 也不能自动识别。

所以想让Spring的配置文件生效,就需要使用@ImportResource注解,此注解标注在一个配置类上即可。

// 导入Spring的配置文件让其生效
@ImportResource(locations = {"classpath:beans.xml"}) 
@SpringBootApplication
public class SpringBootDemoApplication {
	public static void main(String[] args) {
		SpringApplication.run(SpringBootDemoApplication.class, args);
	}
}
  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Spring Boot 提供了多种读取配置文件的方式,以下是其几种常用的方式: 1. application.properties/application.yml:在 src/main/resources 目录下创建 application.properties 或 application.yml 文件,可以在其设置应用程序的配置信息,例如: ``` server.port=8080 spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase spring.datasource.username=root spring.datasource.password=123456 ``` 2. @Value 注解:在代码使用 @Value 注解读取配置信息,例如: ``` @Value("${server.port}") private int serverPort; @Value("${spring.datasource.url}") private String dataSourceUrl; @Value("${spring.datasource.username}") private String dataSourceUsername; @Value("${spring.datasource.password}") private String dataSourcePassword; ``` 3. @ConfigurationProperties 注解:通过 @ConfigurationProperties 注解将配置文件属性值注入到 Bean ,例如: ``` @ConfigurationProperties(prefix = "spring.datasource") public class DataSourceProperties { private String url; private String username; private String password; // getter/setter } ``` 4. Environment 接口:通过 Environment 接口读取配置信息,例如: ``` @Autowired private Environment env; int serverPort = env.getProperty("server.port", Integer.class); String dataSourceUrl = env.getProperty("spring.datasource.url"); String dataSourceUsername = env.getProperty("spring.datasource.username"); String dataSourcePassword = env.getProperty("spring.datasource.password"); ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

止步前行

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

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

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

打赏作者

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

抵扣说明:

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

余额充值