SpringBoot的属性注入


文章目录

  • SpringBoot的属性注入
  • 使用@Value属性值注入
  • 使用@ConfigurationProperties批量注入
  • 第三方配置
  • 松散绑定
  • @ConfigurationProperties vs @Value



使用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   //用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);
    }

输出结果如下

spring boot对象注入 spring boot属性注入_bc

使用@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") //将配置文件中以person开头的属性注入到该类
public class Person {

    private int id; //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注解时,上面会弹出一条提示信息:

spring boot对象注入 spring boot属性注入_java_02

同时当我们在编写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,并进行输出测试。可以看到测试结果输出如下所示:

spring boot对象注入 spring boot属性注入_spring boot对象注入_03

说明我们利用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());
    }

得到输出结果:

spring boot对象注入 spring boot属性注入_spring boot_04

说明这种松散绑定的效果是成功的。
下面给出多种绑定方式:

属性文件中配置

说明

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

应用场景

批量属性绑定

单个属性绑定