从springboot中两个引入配置文件的注解@ConfigurationProperties和@PropertySource分析属性值的注入
第一部分:@ConfigurationProperties部分
@ConfigurationProperties是springboot的一个注解。
会把springboot的默认配置文件application.yml文件的同名属性,绑定到该注解下的类的对应属性上(如果有在@ConfigurationProperties引入prefix属性,则还要对这个属性的值进行yml文件下的前缀匹配,不引入则可以在yml的根位置直接匹配),但是这个注解本身是不会导致被注解的该类注册到spring容器中形成实例对象,需要配合其他注解(如“@Component、@Configuration”),先把当前被注解的类在spring容器中实例化才可以绑定。
一、@ConfigurationProperties + @Component(@Configuration)
(点进@Configuration注解可观察到其内部包含了@Component注解,该注解为配置文件类所主要使用。)
举例说明:
1、在application.yml默认配置文件写入:
test1:
info: goodjob
2、创建配置类:
@Data
@Configuration
@ConfigurationProperties(prefix = "test1")
public class MyConfig {
private String info;
}
3、在测试类中获取info结果
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {UserApplication.class})
public class MyTest {
@Autowired
private MyConfig myConfig;
@Test
public void test1(){
System.out.println("info:"+myConfig.getInfo());
}
}
可见,application.yml配置文件中的info的值已经注入到MyConfig类中的info属性上。
二、@ConfigurationProperties + @Bean
(这里提一下@Bean注解和@Component注解,两者最终都是产生一个bean实例对象注册到spring容器中,但@Component是用于修饰类,表示这个类产生一个实例对象,只能用于自己编写的类;而@Bean是用于修饰方法,表示这个方法返回的实例对象会被注册到spring容器中,可以用于引入第三方库中的类的实例对象的引入,更加灵活。)
举例说明:
1、先创建一个普通的无注解类(除lombok)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Worker {
private String username;
private String password;
}
2、在application.yml中写入配置信息:
test2:
username: jack
password: bigsmall
3、创建配置类:
@Data
@Configuration
public class MyConfig {
@Bean
@ConfigurationProperties(prefix = "test2")
public Worker worker(){
return new Worker();//在这里返回worker对象时,有一个问题,如果这里直接利用有参构造传入值,最终在测试类中是不起作用的,会被注入的值覆盖掉。所以spring注入属性的的值,是在类实例化对象之后进行的。
}
}
4、测试类进行测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {UserApplication.class})
public class MyTest {
@Autowired
private MyConfig myConfig;
@Test
public void test1(){
System.out.println("info:"+myConfig.worker());
}
}
可以发现,Worker类的属性均已被注入数据。
三、@ConfigurationProperties注解普通类,待@EnableConfigurationProperties引入后定义为bean
举例说明:
1、创建普通类,写入@ConfigurationProperties注解,表示该类一旦被实例就会注入属性的值
@Data
@AllArgsConstructor
@NoArgsConstructor
@ConfigurationProperties(prefix = "test2")
public class Worker {
private String username;
private String password;
}
2、写入yml配置文件
test2:
username: jack
password: bigsmall
3、完成配置类,@EnableConfigurationProperties注解将Worker实例化为bean对象
@Data
@Configuration
@EnableConfigurationProperties({Worker.class})
public class MyConfig {
private String info;
@Bean
public Worker worker(){
return new Worker();
}
}
4、测试如上。
四、内部类直接对应配置文件(内部类)
abc:
player1:
username: jack
password: bigsmall
@Data
@Configuration
@ConfigurationProperties(prefix = "abc")//前缀与配置文件abc对应
public class MyConfig {
private Player player1 = new Player();//属性名与配置文件player1对应
@Data
public class Player{
private String username;//内部类属性名与配置文件username对应
private String password;//内部类属性名与配置文件password对应
}
}
第二部分:@PropertySource部分
@PropertySource是spring的一个注解。
在注册到spring容器后,该注解会去扫描其内指定的classpath路径下的配置文件的属性值,将符合名称的值加载到这个spring容器内的Environment对象,全过程不需要在使用这个属性的对象下执行,所以可以在同级别、父级别或者根目录的类(启动类)下进行加载。
这里扫描的配置文件范围与@ConfigurationProperties不同,@ConfigurationProperties是仅能扫描yml主配置文件,而这个注解是用于扫描主配置文件以外的配置文件。
与上面的@ConfigurationProperties注解一样,该注解也是不会去直接把所修饰的类被注册到spring容器中,需要配合其他注解(如“@Component、@Configuration”),把当前的类交给spring容器管理,才能获取到spring容器下的
Environment对象的属性,使用方式有@Value或Environment对象实现。
固定配置文件:
位置:classpath:properties/gj.properties
内容如下:
wk.username=lisa
wk.password=abc
一、@PropertySource + @Configuration配合spring包下的Environment类
@Data
@Configuration
@PropertySource("classpath:/properties/gj.properties")
public class MyConfig {
@Autowired
private Environment env;
}
加载指定的属性文件可以直接把属性配置到 Spring 的 Environment 中,测试类可以通过Environment的对象直接取出配置的属性值。
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {UserApplication.class})
public class MyTest {
@Autowired
private MyConfig myConfig;
@Test
public void test1(){
System.out.println("info:"+myConfig.getEnv().getProperty("wk.username"));
}
}
二、@PropertySource + @Configuration + @Value(内含${})
@Data
@Configuration
@PropertySource("classpath:properties/gj.properties")
public class MyConfig {
@Value("${wk.username}")
private String info;
}
注意@Value注解内的值与配置文件内属性名称一致
三、@Configuration + @PropertySource + @ConfigurationProperties
@Configuration注解负责注册配置类,@PropertySource注解负责扫描指定路径的配置文件,@ConfigurationProperties负责扫描配置文件下的属性内容,看是否有与当前的配置类中相同的属性名,有就进行属性值的赋值。
@Data
@Configuration
@PropertySource("classpath:properties/gj.properties")
@ConfigurationProperties(prefix = "wk")
public class MyConfig {
private String username;
}
第三部分:额外说明下bootstrap.yml、application.yml、application.properties配置文件
application.yml和application.properties为springboot的通用配置文件;
而bootstrap.yml为springcloud所特有的配置文件,需要在总pom中引入约束
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
并且在模块pom中引入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
</dependency>
三者加载顺序从先到后依次为:bootstrap.yml->application.yml->application.properties。
后面加载的配置文件,会覆盖前面的配置文件,比如application.yml里面的name属性会把bootstrap.yml里面的name属性的属性值覆盖掉。
第四部分:总结
| 特性 | **@PropertySource** | **@ConfigurationProperties** |
|---|---|---|
| 功能定位 | 加载外部属性文件到Spring的Environment | 将配置文件属性批量绑定到Java对象的字段 |
| 使用场景 | 动态读取单个属性(如配合@Value) | 类型安全地管理复杂配置(嵌套对象、列表等) |
| 前缀处理 | 不支持前缀过滤 | 支持通过prefix指定配置前缀 |
| 类型安全 | 需手动类型转换(如@Value("${port}") int) | 自动类型转换(字段类型匹配) |
| 文件格式支持 | 仅支持.properties(默认需自定义YAML解析) | 原生支持.properties和.yml |
| 依赖注入方式 | 需配合@Value或Environment对象访问 | 直接注入配置类,无需额外注解 |
| 多文件加载 | 支持通过数组或@PropertySources加载多个文件 | 仅能绑定主配置文件(需结合@PropertySource扩展) |
| 代码侵入性 | 低(仅声明文件路径) | 高(需定义配置类及字段) |
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)