SpringBoot类型安全配置

简介: ## 一个使用@Value(${...})的例子 下面是一段简单的服务器配置的代码: ```java @Data @Component public class ServerConfig { /** 是否启用服务 */ @Value("${ali.server.enabled}") private boolean enabled;

一个使用@Value(${...})的例子

下面是一段简单的服务器配置的代码:

@Data
@Component
public class ServerConfig {

    /** 是否启用服务 */
    @Value("${ali.server.enabled}")
    private boolean enabled;
    /** 服务器的远程地址 */
    @Value("${ali.server.remote-address}")
    private InetAddress remoteAddress;
    /** 服务器的安全配置 */
    @Autowired
    private Security security;

    @Component
    @Data
    public static class Security {

        /** 服务器的用户名 */
        @Value("${ali.server.security.username}")
        private String username;
        /** 用户密码 */
        @Value("${ali.server.security.username}")
        private String password;
        /** 角色列表 */
        @Value("${ali.server.security.roles}")
        private List<String> roles = new ArrayList<>(Collections.singleton("USER"));
    }
}

这段代码定义了如下的配置key:

key 类型 描述
server.enabled boolean 是否启用服务
server.remote-address InetAddress 绑定的ip地址
server.security.username String 安全用户名
server.security.password String 安全密码
server.security.roles List<String> 安全角色

Spring提供的ConversionService会将这些key的字符串配置值自动转换为对应的类型

另外@Value注解还支持SpEL表达式,可以说为Spring项目提供了强大的外部配置绑定能力。但对于复杂配置的管理能力不足:

  1. 基于字符串的表达式没有编译时类型检查
  2. 多处引用配置key时,需要重复引用字面量,容易出错
  3. 不容易重构,对key的命名变更
  4. 对复杂的对象配置比较困难

看上面的例子中Security需要声明为Bean才能支持@Value绑定,然后注入到Server中。如果是更复杂的场景,管理Bean会更困难

  1. 没有配置的元信息,想全局查看配置比较困难,编写配置文件时也没有任何可靠这自动校验很容易写错配置项

SpringBoot提供的类型安全配置方案

SpringBoot提供了@ConfigurationProperties注解,提供类型安全的配置声明方案。

利用@ConfigurationProperties修改上面的例子:

@Data
@Component
@ConfigurationProperties("ali.server")
public class ServerConfig {

    /** 是否启用服务 */
    private boolean enabled;
    /** 服务器的远程地址 */
    private InetAddress remoteAddress;
    /** 服务器的安全配置 */
    private Security security = new Security();

    @Data
    public static class Security {

        /** 服务器的用户名 */
        private String username;
        /** 用户密码 */
        private String password;
        /** 角色列表 */
        private List<String> roles = new ArrayList<>(Collections.singleton("USER"));
    }
}

上述代码定义的配置key与使用@Value注解的例子是相同的,但具有如下特点:

  1. 代码更简单,不依赖key的字面量
  2. Security不需要声明为Bean,不需要注入到Server,可以支持更复杂的声明
  3. 结合spring-boot-configuration-processor提供的注解处理器可以自动生成配置的元信息

元信息中包含key的命名及从javadoc中读取的说明信息以及默认值。

有了这些元信息,在编写配置文件是使用IDEA编辑器可以自动弹出提示

image-20190823172920045.png

有了编辑的辅助,相对不容易写错配置,且可以很容易看到看有哪些配置可以使用

因为有了这些元信息,IDEA的重构(重命名)命令可以自动做全局重构

  1. 避免使用字面量,不易出错,鼓励使用Bean注入来使用配置信息
  2. 多处引用Bean来读取配置时,都是Java代码级别的引用有编译时检查

ConfigurationProperties支持Spring Validation

@Data
@Component
@Validated
@ConfigurationProperties("ali.server")
public class Server {

    /** 是否启用服务 */
    private boolean enabled;
    /** 服务器的远程地址 */
    @NotNull
    private InetAddress remoteAddress;
    /** 服务器的安全配置 */
    private Security security = new Security();

    @Data
    public static class Security {

        /** 服务器的用户名 */
        @NotBlank
        private String username;
        /** 用户密码 */
        @Pattern(regexp = "\\w+\\d+")
        private String password;
        /** 角色列表 */
        @Size(min = 1, max = 10)
        private List<String> roles = new ArrayList<>(Collections.singleton("USER"));
    }
}

利用Spring Validation集成,可以对配置提供灵活强大的校验能力。

支持第三方组件配置

如果依赖一个需要配置的第三方组件,要如何为其编写外部依赖?下面以DruidDataSource为例:

首先使用@Value来实现,那么代码如下:

@Data
@Component
public class DataSourceConfig {
    @Value("db.url")
    private String url;
    @Value("db.username")
    private String username;
    @Value("db.password")
    private String password;
    @Value("db.driver-class-name")
    private String driverClassName;
}

@Configuration
@ComponentScan
public class DataSourceConfiguration {

    @Bean
    public DruidDataSource dataSource(DataSourceConfig config) {
        DruidDataSource ds = new DruidDataSource();
        ds.setUrl(config.getUrl());
        ds.setUsername(config.getUsername());
        ds.setPassword(config.getPassword());
        ds.setDriverClassName(config.getDriverClassName());
        return ds;
    }
}
db.url=jdbc://....
db.username=root
db.password=....
db.driver-class-name=DriverClassName

上述代码具有如下特点:

  1. 需要一个额外的配置类来做值绑定
  2. 创建DruidDataSource实例时需要做属性拷贝(可以使用BeanUtils.copyProperties替代)
  3. 灵活性差,增加配置需要修改DataSourceConfig类

加入现在要配置数据源的最大连接数,那么需要给DataSourceConfig类增加一个maxActive属性

下面使用@ConfigurationProperties来改写,代码如下:

@Configuration
public class DataSourceConfiguration {

    @Bean
    @ConfigurationProperties("db")
    public DruidDataSource dataSource() {
        return new DruidDataSource();
    }
}

SpringBoot会自动识别DruidDataSource的所有属性,自动绑定到约定的key上。

例如有DruidDataSource.setMaxActive定义了一个maxActive属性,那么可以使用db.max-active来对其进行配置。

所以这段代码可以使用与上面使用@Value注解时同样的配置进行初始化。

目录
相关文章
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
9天前
|
Java 开发者 微服务
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
28 0
|
1月前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
46 4
|
1月前
|
Java 数据库连接 Maven
springBoot:项目建立&配置修改&yaml的使用&resource 文件夹(二)
本文档介绍了如何创建一个基于Maven的项目,并配置阿里云仓库、数据库连接、端口号、自定义启动横幅及多环境配置等。同时,详细说明了如何使用YAML格式进行配置,以及如何处理静态资源和模板文件。文档还涵盖了Spring Boot项目的`application.properties`和`application.yaml`文件的配置方法,包括设置数据库驱动、URL、用户名、密码等关键信息,以及如何通过配置文件管理不同环境下的应用设置。
114 1
|
1月前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
38 0
|
13天前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
26 2
 SpringBoot入门(7)- 配置热部署devtools工具
|
3天前
|
存储 前端开发 JavaScript
springboot中路径默认配置与重定向/转发所存在的域对象
Spring Boot 提供了简便的路径默认配置和强大的重定向/转发机制,通过合理使用这些功能,可以实现灵活的请求处理和数据传递。理解并掌握不同域对象的生命周期和使用场景,是构建高效、健壮 Web 应用的关键。通过上述详细介绍和示例,相信读者能够更好地应用这些知识,优化自己的 Spring Boot 应用。
12 3
|
12天前
|
Java 数据库连接
SpringBoot配置多数据源实战
第四届光学与机器视觉国际学术会议(ICOMV 2025) 2025 4th International Conference on Optics and Machine Vision
40 8
|
9天前
|
Java 数据库连接 数据库
springboot启动配置文件-bootstrap.yml常用基本配置
以上是一些常用的基本配置项,在实际应用中可能会根据需求有所变化。通过合理配置 `bootstrap.yml`文件,可以确保应用程序在启动阶段加载正确的配置,并顺利启动运行。
19 2
|
14天前
|
分布式计算 关系型数据库 MySQL
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型
SpringBoot项目中mysql字段映射使用JSONObject和JSONArray类型 图像处理 光通信 分布式计算 算法语言 信息技术 计算机应用
36 8

热门文章

最新文章

下一篇
无影云桌面