SpringBoot的属性注入
使用Spring Boot全局配置文件设置属性时:
- 如果配置属性是Spring Boot已有属性,例如服务端口server.port,那么Spring Boot内部会自动扫描并 读取这些配置文件中的属性值并覆盖默认属性。
- 如果配置的属性是用户自定义属性,例如刚刚自定义的Person实体类属性,还必须在程序中注入这些配 置属性方可生效。
属性注入常用注解包括:
- @Configuration:声明一个类作为配置类
- @Bean:声明在方法上,将方法的返回值加入Bean容器
- @Value:属性注入
- @ConfigurationProperties(prefix = “jdbc”):批量属性注入
- @PropertySource(“classpath:/jdbc.properties”)指定外部属性文件。在类上添加
使用@Value属性值注入
以配置数据库连接对象案例为例,定义一个JdbcConfiguration实体类,用于配置连接参数和返回数据池连接对象。参数值在application.properties配置文件中编写,并利用@Value注解注入。
JdbcConfiguration实体类利用@Value属性值注入的代码如下:
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
public class JdbcConfiguration {
@Value("${jdbc.url}")
String url;
@Value("${jdbc.driverClassName}")
String driverClassName;
@Value("${jdbc.username}")
String username;
@Value("${jdbc.password}")
String password;
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl(url);
dataSource.setDriverClassName(driverClassName);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
在dataSource() 方法上添加@Bean注解,该注解用在方法上,用于将方法的返回值添加到bean容器中。接下里,在application.properties配置文件中添加如下配置:
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/sys?serverTimezone=GMT%2b8
jdbc.username=root
jdbc.password=123
最后,我们在项目的测试类下进行测试,打印连接结果
@Test
public void jdbcConfiguration() throws SQLException {
DataSource dataSource = jdbcConfiguration.dataSource();
Connection connection = dataSource.getConnection();
System.out.println(connection);
}
输出结果如下
使用@ConfigurationProperties批量注入
通过一个案例来对SpringBoot使用@ConfigurationProperties注解实现批量注入的过程进行讲解
在项目中定义两个实体类,利用application.properties配置文件中的自定义配置属性注入到实体类对应的属性中。通过这种方式,实现实体类参数值的注入。
打开项目工程文件,在pojo包下,创建两个实体类Pet和Person
public class Pet {
private String type;
private String name;
public String getType()
{
return type;
}
public void setType(String type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Person实体类
import lombok.Data;
import lombok.ToString;
import java.util.List;
import java.util.Map;
@Data
@ToString
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private int id;
private String name;
private List hobby;
private String[] family;
private Map map;
private Pet pet;
}
Person类中利用注解@Data和@ToString来便于构造Get和Set以及ToString方法,@ConfigurationProperties(prefix = “person”)注解的作用是将配置文件中以person开头的属性值通过setXX()方法注入到实体类对应属性中。@Component注解的作用是将当前注入属性值的Person类对象作为Bean组件放到Spring容器中,只有这样才能被@ConfigurationProperties注解进行赋值。
接下来打开项目的resources目录下的application.properties配置文件,在该配置文件中编写需要对Person类设置的配置属性
person.id=1
person.name=tom
person.hobby=音乐,篮球,阅读
person.family=father,mother
person.map.k1=v1
person.map.k2=v2
person.pet.type=dog
person.pet.name=旺财
在上面的配置文件中,由于Person实体类中变量map是Map类型,是键值对的形式,所以在赋值是需要以k1,k2的形式指定key-value。同时,pet变量时Pet实体类,因此也需要三层调用指定对应Pet实体类每个变量的值。
这里需要注意的是,当我们在Person实体类上添加@ConfigurationProperties注解时,上面会弹出一条提示信息:
同时当我们在编写application.properties配置文件时,由于要配置的Person对象属性是我们自定义的,SpringBoot无法自动识别,所以不会有任何书写提示(而当我们写server.port属性时,是会有书写提示的)。在实际开发中,为了出现代码提示的效果来方便配置,在使用@ConfigurationProperties注解进行配置文件属性值注入时,可以在pom.xml文件中添加一个Spring Boot提供的配置处理器依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional>
</dependency>
在pom.xml中添加上述配置依赖后,还需要重新运行项目启动类或者使用“Ctrl+F9”快捷键(即 Build Project)重构当前Spring Boot项目方可生效
构造好后,打开项目测试类,在该测试类中引入Person实体类Bean,并进行输出测试。可以看到测试结果输出如下所示:
说明我们利用application.properties配置文件和@@ConfigurationProperties注解进行批量注入是成功的
第三方配置
除了 @ConfigurationProperties 用于注释类之外,您还可以在公共 @Bean 方法上使用它。
当要将属 性绑定到控件之外的第三方组件时,这样做特别有用。
比如创建一个其它组件类
@Data
public class AnotherComponent {
private boolean enabled;
private InetAddress remoteAddress;
}
创建MyService
@Configuration
public class MyService {
@ConfigurationProperties("another")
@Bean
public AnotherComponent anotherComponent(){
return new AnotherComponent();
}
}
配置文件
another.enabled=true
another.remoteAddress=192.168.10.11
测试类
@Autowired
private AnotherComponent anotherComponent;
@Test
public void anotherComponent()
{
System.out.println(anotherComponent);
}
得到输出结果:
AnotherComponent(enabled=true, remoteAddress=/192.168.10.11)
松散绑定
Spring Boot使用一些宽松的规则将环境属性绑定到@ConfigurationProperties bean,因此环境属性名 和bean属性名之间不需要完全匹配。
例如属性类:
@Data
@Component
@ConfigurationProperties("acme.my-person.person")
public class OwnerProperties {
private String firstName;
}
在配置文件对firstName 的赋值可以采用如下形式:
aceme.my-person.person.first-name:Stephen
在项目测试类中进行测试:
@Autowired
private OwnerProperties ownerProperties;
@Test
public void ownerProperties()
{
System.out.println(ownerProperties.getFirstName());
}
得到输出结果:
说明这种松散绑定的效果是成功的。 下面给出多种绑定方式:
属性文件中配置 | 说明 |
---|
acme.my-project.person.first-name | 羊肉串模式case, 推荐使用 | acme.myProject.person.firstName | 标准驼峰模式 | acme.my_project.person.first_name | 下划线模式 | ACME_MYPROJECT_PERSON_FIRSTNAM | 大写下划线,如果使用系统环境时候推荐使用 |
@ConfigurationProperties vs @Value
特征 | @ConfigurationProperties | @Value |
---|
宽松的绑定 | yes | Limited | 元数据支持 | yes | no | SpEL表达式 | no | yes | 应用场景 | 批量属性绑定 | 单个属性绑定 |
|