0
点赞
收藏
分享

微信扫一扫

SpringBoot-学习-6-属性注入原理

文章目录


前言

上面我们用一些案例测试使用了全局配置的一些场景和两种格式的配置文件的使用方法,那么大家肯定都很想知道到底是怎么注入进去的,前面我们用到的@ConfigurationProperties具体是怎么做的呢?我们接下来继续一起学习

使用SpringBoot全区配置文件设置属性时:
如果配置属性是SpringBoot已有属性,例如服务端口server.port,那么SpringBoot内部会自动扫描并读取这些配置中的属性值并覆盖默认属性。
如果配置的属性是用户自定义的属性,例如上一篇中自定义的Person实体类属性,还必须在程序中注入这些配置属性方可生效


一、属性注入的常用注解

1.@Configuration

Spring中就已经接触过的注解,作用是声明一个类作为配置类,项目启动的时候就会架子啊这个类

2.@Bean

声明在方法上,将方法的返回值加入Bean容器(IOC容器)

3.@Value

同样是Spring提供的注解,SpringBoot继承了这个注解,作用是进行单个的属性注入,一般结合Spring EL表达式进行使用

4.@ConfigurationProperties

就是我们上一篇使用过的注解,主要作用就是进行批量属性注入
用法:@ConfigurationProperties(prefix = “jdbc”)

5.@PropertySource

指定外部属性文件。在类上添加,作用是完成一些外部属性文件的加载和注入
用法:@PropertySource(“classpath:/jdbc.properties”)

二、常用注解的使用

1.@Value注解注入

(1)、导入数据源链接的依赖

<dependency>
    <groupId>com.github.drtrang</groupId>
    <artifactId>druid-spring-boot2-starter</artifactId>
    <version>1.1.10</version>
</dependency>

(2)、application.properties添加信息

# 数据源配置
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/lagou
jdbc.username=root
jdbc.password=lx246810

(3)、配置数据源

创建JdbcConfiguration类:使用spring中的value注解对每个属性进行注入,用bean注解将返回值添加到容器中

@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;
    }

    @Override
    public String toString() {
        return "JdbcConfiguration{" +
                "url='" + url + '\'' +
                ", driverClassName='" + driverClassName + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

(4)、测试一下

测试一下JdbcConfiguration的情况
在这里插入图片描述
再来测试一下dataSource的情况
在这里插入图片描述

2.@ConfigurationProperties批量注入

(1)、对类的属性进行批量注入

新建一个JdbcProperties类,用来进行属性注入

@ConfigurationProperties(prefix = "jdbc")
public class JdbcProperties {
    private String url;
    private String driverClassName;
    private String username;
    private String password;

    //省略getset方法和tostring
}
注意,如果顶部警告有警告:springboot 配置注释处理器未配置 需要添加spring-boot-configuration-processor依赖然后重新编译
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

接着发现,仍然有红色警告
在这里插入图片描述
@EnableConfigurationProperties 是 Spring Boot 提供的一个注解,使用该注解用于启用应用对注解@ConfigurationProperties的支持
在这里插入图片描述
添加@Configuration注解的原因是为了在启动的时候就将这个类加载成一个bean注册到容器中,方便我们进行测试

在application.properties文件添加信息

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/lagou
jdbc.username=root
jdbc.password=lx246810

测试一下

@Autowired
    private JdbcProperties jdbcProperties;

    @Test
    public void test2(){
        System.out.println(jdbcProperties);
    }

在这里插入图片描述
可以看到是我们想要的结果

(2)、第三方配置

@ConfigurationProperties 除了用于注释本地的类之外,您还可以在公共 @Bean 方法上使用它。
也就是说如果我们想要通过配置文件给一个第三方jar包中的组件(类)进行赋值的话,也可以使用@ConfigurationProperties注解

我们来看一下效果:
首先创建一个其他的组件类(生成toString和getset方法)注意:这个类是我们用来模拟第三方jar包中的类

public class AnotherComponent {
    private boolean enabled;
    private InetAddress remoteAddress;
}

因为是第三方包的类,所以我们无法在上面加@ConfigurationProperties注解进行属性注入

接下来我们依然在配置文件中配置下该类的属性

another.enabled=true
another.remoteAddress=192.168.10.11

然后创建一个Service
我们都知道如果我想要把一个第三方包的类实例化到本地容器就需要用到@Bean注解,这里我们加上@Configuration注解是为了启动注入

然后我们只需要在实例化的时候加上@ConfigurationProperties(“another”)注解就可以做到给这个第三方类赋值了

@Configuration
public class MyService {
    @ConfigurationProperties("another")
    @Bean
    public AnotherComponent anotherComponent(){
        return new AnotherComponent();
    }
}

测试一下:

@Autowired
    private AnotherComponent anotherComponent;
    @Test
    public void myServiceTest(){
        System.out.println(anotherComponent);
    }

在这里插入图片描述
可以看到这样我们就给这个第三方类的属性赋上值了

(3)、松散绑定

SpringBoot使用一些宽松的规则将环境属性绑定到@ConfigurationProperties bean,因此环境属性名和bean属性名之间不需要完全匹配也可以
举个例子:

@Component
@ConfigurationProperties("owner-properties.test")
public class OwnerProperties {
    private String firstName;// 驼峰命名方式
}

我们能看到上面的OwnerProperties类我们开启了属性注入,重点是firstName变量的命名方式是驼峰的

但是我们在配置文件中如果配置的是羊肉串格式能不能行呢?

owner-properties.test.first-name: tom

我们测试一下
在这里插入图片描述
可以看到依然可以注入正确的值,这个就是松散绑定啦

注意这里松散不是只对属性名,对整个key都是起作用的

这里列举一下支持的所有的格式以及示例:
羊肉串模式:owner-properties.test.first-name: tom
标准驼峰模式:ownerProperties.test.firstName: tom
下划线模式:owner_properties.test.first_name: tom
大写下划线模式:OWNER_PROPERTIES.TEST.FIRST_NAME: tom

我们可以看到我们的示例中是整个key一起进行格式转换,并非只对属性名进行转换

三、@ConfigurationProperties vs @Value

基本特征
@ConfigurationProperties

  • 与@Bean结合为属性赋值
  • 与@PropertySource(只能用于properties文件)结合读取指定文件
  • 与@Validation结合,支持JSR303进行配置文件值的校验,如@NotNull@Email等

@Value

  • 为单个属性赋值
  • 支持属性上的SpEL表达式

下面以表格的形式整理一下:

@ConfigurationProperties@Value
场景批量注入配置文件中的属性一个个指定
松散绑定支持不支持
SpEL不支持支持
JSR303数据校验支持不支持
复杂类型封装支持不支持

补充知识:

1、JSR303数据校验

这里提供两篇文章大家可以自己看下:
JSR 303 - Bean Validation 简介及使用方法
JSR303参数校验实现

2、SpEL表达式

这里给大家的是核心技术中的一篇,有空的话可以仔细拜读一下,还是很清楚且易懂的
Spring 表达式语言 (SpEL)

举报

相关推荐

0 条评论