【Spring Boot 快速入门】六、配置文件

目录

配置文件

参数配置化

在文件上传部分中,UserServiceImpl 中写死了上传目录路径:

java 复制代码
String uploadDir = "IDEA-workspace/demo3/images/";

这个写法 不灵活、不安全、可维护性差。比如:

  • 如果换一台服务器,这个路径可能不存在;
  • 如果部署到 Linux 环境,路径规则会变;
  • 如果有多个环境(开发、测试、生产),每个环境的路径不同;
  • 如果要改动上传路径,还要改代码、重新打包部署。

因此,更推荐的做法是:将这种"易变的信息"写到配置文件中,由代码读取它。

首先要在 application.properties 中配置上传路径:

properties 复制代码
# 上传文件保存的绝对路径(根据你机器上的真实目录填写)
file.upload.dir=/Users/yourname/project/demo3/images/

# 静态资源访问路径(浏览器访问时的前缀)
file.access.prefix=/images/

然后使用 Spring Boot 提供的 @Value 注解将配置文件中的值注入到变量中:

java 复制代码
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Value("${file.upload.dir}")
    private String uploadDir;

    @Value("${file.access.prefix}")
    private String accessPrefix;

    // ...
}

最后在上传逻辑中使用这些变量即可:

java 复制代码
// 确保目录存在
File dir = new File(uploadDir);
if (!dir.exists()) {
    dir.mkdirs();
}

// 保存文件
String path = UUID.randomUUID().toString() + ext;
image.transferTo(new File(uploadDir + path));

// 访问路径用于存入数据库(浏览器访问时的路径)
String accessPath = accessPrefix + path;

User user = new User(null, username, name, gender, accessPath, LocalDateTime.now(), LocalDateTime.now());
userMapper.adduser(user);

yml 配置文件

基本语法:

  • 大小写敏感
  • 数值前必须有空格作为分隔符
  • 使用缩进表示层级关系,缩进时不允许使用 Tab 键,只能用空格(IDEA 中会自动将 Tab 转换为空格)
  • 缩进的空格数目不重要,只要相同层级的元素左侧对齐即可
  • # 表示注解,从这个字符一直到行尾都会被解析器忽略

yml 配置文件是层级格式:

yaml 复制代码
server:
  port: 8080
  address: 127.0.0.1

yml 数据格式:

  • 对象/Map 集合:

    yaml 复制代码
    user:
      name: zhangsan
      age: 18
      password: 123456
  • 数组/List/Set 集合:

    yaml 复制代码
    hobby:
      - java
      - game
      - sport

.yml vs .properties 区别:

特点 .properties .yml
格式 key=value 层级缩进式结构
可读性 较弱 强(适合结构复杂的配置)
层级结构 使用 . 拼接 使用缩进

将上面的 application.properties 文件改为 application.yml 文件:

yaml 复制代码
file:
  upload:
    dir: /Users/yourname/project/demo3/images/
  access:
    prefix: /images/

也可以像 application.properties 文件那样使用 @Value 注解将配置文件中的值注入到变量中

@ConfigurationProperties

每个配置参数对应的变量名都要使用 @Value 来注入值:

java 复制代码
@Service
public class UserServiceImpl implements UserService {

    @Value("${file.upload.dir}")
    private String uploadDir;

    @Value("${file.access.prefix}")
    private String accessPrefix;

    // ...
}

如果配置的参数很多,就要写很多个 @Value 来进行注入,这样就显得代码很臃肿。

为了解决这个问题,可以通过创建一个配置类来定义变量,然后使用 @ConfigurationProperties 来注入值。

具体步骤如下:

  1. 创建配置类 FileProperties,并交由 IOC 容器管理:

    java 复制代码
    @Data
    @Component
    @ConfigurationProperties(prefix = "file"){
        private Upload upload;
        private Access access;
    
        @Data
        public static class Upload {
            private String dir;
        }
    
        @Data
        public static class Access {
            private String prefix;
        }
    }

    注:如果两个配置参数的前缀一致,比如说:

    yaml 复制代码
    file:
      upload:
        dir: /Users/yourname/project/demo3/images/
        prefix: /images/

    配置类就为:

    java 复制代码
    @Data
    @Component
    @ConfigurationProperties(prefix = "file.upload")
    public class FileUploadProperties {
        private String upload;
        private String access;
    }
  2. 使用配置类:

    java 复制代码
    import org.springframework.beans.factory.annotation.Autowired;
    
    @Service
    public class UserServiceImpl implements UserService {
    
        @Autowired
        private FileUploadProperties fileProps;
    
        public void adduser(...) {
            String uploadDir = fileProps.getUpload().getDir();
            String accessPrefix = fileProps.getAccess().getPrefix();
            // ...
        }
    }
  3. 配置依赖(可选):

    xml 复制代码
    <dependency>
    	<groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-configuration-processor</artifactId>
    </dependency>

@ConfigurationProperties 与 @Value:

  • 相同点:都是用来注入外部配置属性的
  • 不同点:
    • @Value 注解只能一个一个的进行外部属性的注入
    • @ConfigurationProperties 可以批量的将外部的属性配置注入到 Bean 对象的属性中
相关推荐
Filotimo_8 分钟前
Spring Boot 整合 JdbcTemplate(持久层)
java·spring boot·后端
李慕婉学姐20 分钟前
【开题答辩过程】以《“饭否”食材搭配指南小程序的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·spring·小程序
abments2 小时前
pgsql timestamp without time zone > character varying解决方案
java
sanggou2 小时前
大数据量查询处理方案 - 内存优化与高效展示
java
没有bug.的程序员2 小时前
Java 字节码:看懂 JVM 的“机器语言“
java·jvm·python·spring·微服务
-大头.2 小时前
深入理解 Java 内存区域与 JVM 运行机制
java·jvm
没有bug.的程序员2 小时前
JVM 整体架构:一套虚拟机的心脏与血管
java·jvm·spring boot·spring cloud·架构
晨枫阳3 小时前
不同语言的元组对比
java·前端·javascript
悟能不能悟3 小时前
怎么在idea合并2个个branch
java·ide·intellij-idea
i02084 小时前
SpringBoot 项目配置
java·spring boot·后端