【SpringBoot】Bean属性绑定

举报
雪月清 发表于 2022/05/25 20:59:51 2022/05/25
【摘要】 SpringBoot自定义Bean属性绑定、第三方Bean属性绑定、松散绑定、Bean的属性校验

1.自定义Bean属性绑定

  • 在配置文件application.yml 中配置参数
servers:        
  ipAddress: 192.168.0.1
  port: 2345
  timeout: -1

(注:不要写成server 这个是默认属性给tomcat服务器配置参数的)

  • 创建实体类(Bean)

    其中实体类的属性对应配置文件中配置的参数,相当于读取 配置文件 中的内容

@Data
//lombok自动生成get set方法
@Component
//使spring容器能够扫描到此类并注入到bean中
@ConfigurationProperties(prefix = "servers")
//加载配置文件中的属性 前缀为services 内容会自动按照属性名对应

public class ServerConfig {
   private String ipAddress;
   private int port;
   private long timeout;


}

注:@Data 使用lombok插件 自动生成get / set 方法,记得现在pom.xml中导入Lombok的坐标。

@Component Spring中的注解,使spring容器能够扫描到此类 自动封装为Bean 交与容器管理

@ConfigurationProperties(prefix = "servers") 加载配置文件中的属性 前缀为services 内容会自动按照属性名对应进行读取

  • 获取自定义的Bean
@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        //获取容器对象
        ConfigurableApplicationContext run = SpringApplication.run(DemoApplication.class, args);
        //通过类名获取Bean
        ServerConfig bean = run.getBean(ServerConfig.class);
        System.out.println(bean);


    }

}

springboot启动类中 ConfigurableApplicationContext 是获取spring容器对象 ,然后通过容器对象获取其中的ServerConfig类对应的Bean ,就是我们自定义的Bean

输出结果:
在这里插入图片描述

2.第三方bean属性绑定

以 数据源druid 为例

  • 在pom.xml中导入第三方库坐标
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.2.9</version>
</dependency>
  • 在配置类中创建Bean

可以在任意的配置类中 加载 数据源druid 的Bean,配置类就是可以被spring容器描扫到的类,一种简单的实现方式自己创建一个类加上@Component注解就可以当作一个配置类,比如之前的ServerConfig类。

SpringBoot的启动类 @SpringBootApplication 注解 中包含很多注解其中就有@Component 因此可以在启动类中配置Bean

@SpringBootApplication
public class Demo05Application {

    //通过 @Bean 创建Bean
    @Bean
    public DruidDataSource dataSource(){
        DruidDataSource dataSource = new DruidDataSource();
        return  dataSource;
    }
    
    public static void main(String[] args) {
        //获取容器对象
        ConfigurableApplicationContext run = SpringApplication.run(Demo05Application.class, args);

        DruidDataSource dataSource = run.getBean(DruidDataSource.class);
        System.out.println(dataSource);

    }

}
  • 输出结果:
    在这里插入图片描述

输出一堆参数,且参数值均没有初始化,这是由于Druid是懒加载,只有连接数据库时才会初始化

如何给第三方Bean注入数据

通过创建Bean的时候直接给某属性赋值 或者配置文件 读入

  • 直接赋值
@Bean
public DruidDataSource dataSource(){
    DruidDataSource dataSource = new DruidDataSource();
    dataSource.setDriverClassName("com.mysql.jdbc.Driver456");
    return  dataSource;
}
  • 配置文件读入
datasource:
  driverClassName: com.mysql.jdbc.Driver456

@ConfigurationProperties(prefix = "datasource") 注解读入配置文件数据

@Bean
@ConfigurationProperties(prefix = "datasource")
public DruidDataSource dataSource(){
    DruidDataSource dataSource = new DruidDataSource();
    
    return  dataSource;
}

输出结果:在这里插入图片描述

前面我们一直说配置类,配置类是什么?

配置类就是可以被spring容器加载的类,一种简单的实现方式是 自己创建一个类加上@Component注解就可以当作一个配置类。

  • 缺点: 如果我们有几十个类,哪些类是配置类哪些类不是呢?我们总不能一个个去看有没有@Component注解,这样看起来很混乱

我们使用另一个注解 @EnableConfigurationProperties({类名...}) 参数为一个数组,数组中的元素就是 配置类的类名。 比如:@EnableConfigurationProperties(ServerConfig.class) (只有一个元素{}可省略)
在这里插入图片描述

此时同样可以获取 Bean 及 Bean所绑定的属性值

注:如果使用@EnableConfigurationProperties() 注解,那么@Component 就要去除,否则会报 NoUniqueBeanDefinitionException 每个Bean都是独一无二的,两个注解造成Bean冲突了

3.松散绑定

3.1属性绑定模式

@ConfigurationProperties注解绑定属性支持属性名松散绑定

以ServerConfig类为例

@ConfigurationProperties(prefix = "servers")
public class ServerConfig {
   private String ipAddress;
   private int port;
   private long timeout;

}

支持的属性绑定模式:

  • 驼峰模式
servers:
  ipAddress: 192.168.0.1
  port: 2345
  timeout: -1
  • 下划线模式
servers:
  ip_address: 192.168.0.1
  port: 2345
  timeout: -1
  • 中划线模式
servers:
  ip-address: 192.168.0.1
  port: 2345
  timeout: -1
  • 常量模式
servers:
  IP_ADDRESS: 192.168.0.1
  port: 2345
  timeout: -1
  • 任意模式
servers:
  IP_ADD_R-E_SS: 192.168.0.1
  port: 2345
  timeout: -1

总结:@ConfigurationProperties注解支持属性松散绑定,属性名大小写忽略、下划线 _中划线 - 忽略。

注: 支持松散绑定的是@ConfigurationProperties注解,其他注解比如@Value就不支持,而springboot官方建议使用前者

3.2绑定前缀名命名规范

@ConfigurationProperties注解中的参数也就是prefix前缀名的命名规范:

仅能使用纯小写字母、数字、下划线作为合法的字符

比如这样写就不合法

@ConfigurationProperties(prefix = "Servers")

控制台报错信息


Configuration property name 'Servers' is not valid:

Invalid characters: 'S'
Bean: Servers-com.xue.config.ServerConfig
Reason: Canonical names should be kebab-case ('-' separated), lowercase alpha-numeric characters and must start with a letter

注:并非是我们配置文件属性名是servers,而这边前缀名是Servers 大小写不匹配的问题,即使配置文件属性名改为Servers,依旧会报相同的错误,这是由于绑定前缀名命名规范的问题。

事实上,在修改 绑定前缀名命名 为 Servers 时,编译器就会报错
在这里插入图片描述

4.Bean的属性校验

Bean的属性一般都有自己的格式或者类型,比如 端口 port 是数字并且要在规定范围内 ,如果我们写成字符就不行了,不是说不能用port属性,而是port属性作为tomcat服务器端口号注入的时候会报错。所以我们需要属性校验

  • 在pom.xml中导入JSR303规范接口坐标,并导入 hibernate框架提供的校验器做实现类
<dependency>
    <groupId>javax.validation</groupId>
    <artifactId>validation-api</artifactId>
</dependency>
   <!--         使用hibernate框架提供的校验器做实现类-->
        <dependency>
            <groupId>org.hibernate.validator</groupId>
            <artifactId>hibernate-validator</artifactId>
        </dependency>

注:这些依赖都没有写版本号,这是由于spring-boot-starter-parent 总的坐标默认有版本控制,这些依赖都有对应整合好的版本号

  • 对需要进行属性校验的Bean添加 @Validated 注解 开启属性校验
@Data
@ConfigurationProperties(prefix = "servers")
//加载配置文件中的属性 前缀为services 内容会自动按照属性名对应
@Validated
//开启对当前bean的属性注入校验
public class ServerConfig {
   private String ipAddress;
   private int port;
   private long timeout;

}
  • 设置具体的规则
@Data
@ConfigurationProperties(prefix = "servers")
//加载配置文件中的属性 前缀为services 内容会自动按照属性名对应
@Validated
//开启对当前bean的属性注入校验
public class ServerConfig {
   @Max(value = 8888,message = "最大值不能超过8888")
   @Min(value = 202,message = "最小值不能低于202")
   private String ipAddress;
   private int port;
   private long timeout;

}

输出结果:
输出结果

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

举报
请填写举报理由
0/200