1-4 项目结构

2 阅读3分钟

1-4 项目结构

概念解析

标准项目结构

src/
├── main/
│   ├── java/
│   │   └── com/example/demo/
│   │       ├── DemoApplication.java      # 启动类
│   │       ├── config/                    # 配置类
│   │       ├── controller/                # 控制器
│   │       ├── service/                   # 服务层
│   │       │   ├── impl/                  # 服务实现
│   │       │   └── UserService.java
│   │       ├── repository/                # 数据访问层
│   │       ├── entity/                    # 实体类
│   │       ├── dto/                       # 数据传输对象
│   │       ├── vo/                        # 视图对象
│   │       ├── mapper/                    # MyBatis Mapper
│   │       ├── exception/                 # 自定义异常
│   │       └── util/                      # 工具类
│   └── resources/
│       ├── application.yml                # 主配置文件
│       ├── application-dev.yml            # 开发环境
│       ├── application-prod.yml           # 生产环境
│       ├── static/                        # 静态资源(CSS/JS/图片)
│       └── templates/                     # 模板文件(Thymeleaf/Freemarker)
└── test/
    └── java/
        └── com/example/demo/              # 测试代码

配置文件优先级

Spring Boot 配置文件加载顺序(从高到低):

优先级配置文件说明
1命令行参数--spring.config.location
2OS 环境变量SPRING_CONFIG_ADDITIONAL_LOCATION
3jar 包外配置文件./config/application.yml
4jar 包内配置文件classpath:application.yml

多环境配置切换

# 通过命令行指定
java -jar app.jar --spring.profiles.active=dev

代码示例

1. 多环境配置文件

application.yml(公共配置)

server:
  port: 8080

# 公共配置
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver

application-dev.yml(开发环境)

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/dev_db
    username: root
    password: root

logging:
  level:
    com.example: DEBUG

application-prod.yml(生产环境)

spring:
  datasource:
    url: jdbc:mysql://prod-db-server:3306/prod_db
    username: ${DB_USER}
    password: ${DB_PASSWORD}

logging:
  level:
    com.example: INFO

2. YAML 配置示例

# 完整配置示例
spring:
  application:
    name: springboot-demo

  profiles:
    active: dev

  datasource:
    url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      maximum-pool-size: 20
      minimum-idle: 5
      connection-timeout: 30000

  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        format_sql: true

  redis:
    host: localhost
    port: 6379
    password: ${REDIS_PASSWORD:}
    database: 0
    timeout: 3000

server:
  port: 8080
  servlet:
    context-path: /api
  tomcat:
    threads:
      max: 200
      min-spare: 10

logging:
  level:
    root: INFO
    com.example: DEBUG
  pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n"

3. Properties 配置转换

YAML 转 Properties 示例:

# application.properties 等价于上面的 YAML
spring.application.name=springboot-demo
spring.profiles.active=dev

# 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/demo
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# JPA 配置
spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.format_sql=true

# 端口
server.port=8080

4. 自定义配置文件

读取自定义配置

# application.yml
app:
  name: demo
  version: 1.0.0
  features:
    - login
    - register
// 方式一:@ConfigurationProperties(推荐)
@Component
@ConfigurationProperties(prefix = "app")
@Data
public class AppProperties {
    private String name;
    private String version;
    private List<String> features;
}

// 方式二:@Value
@Value("${app.name}")
private String appName;

常见坑点

⚠️ 坑 1:配置文件乱码

问题:YAML 中中文乱码

解决

  1. 确保 IDEA 设置为 UTF-8
  2. 或使用 Unicode 转义:app.name: \u6D4B\u8BD5

⚠️ 坑 2:多环境激活失败

问题application-dev.yml 没有被激活

排查

# 检查启动日志中的 active profiles
# 应该显示:The following profiles are active: dev

常见错误

# 错误写法
spring:
  profile: dev  # 应该是 profiles

# 正确写法
spring:
  profiles:
    active: dev

⚠️ 坑 3:@ConfigurationProperties 不生效

问题:注入的配置值为 null

解决

// 1. 确保有 @EnableConfigurationProperties
@SpringBootApplication
@EnableConfigurationProperties(AppProperties.class)
public class SpringBootApplication { }

// 2. 或者添加 @Component
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties { }

⚠️ 坑 4:resources 下文件找不到

问题classpath:mapper/UserMapper.xml 找不到

解决:确保 pom.xml 配置了资源打包

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
        </resource>
    </resources>
</build>

面试题

Q1:Spring Boot 的配置加载顺序是什么?

参考答案

从高到低:

  1. 命令行参数--spring.config.location=/path/to/config
  2. OS 环境变量SPRING_CONFIG_ADDITIONAL_LOCATION
  3. jar 包外部./config/application.yml
  4. jar 包内部classpath:application.yml
  5. @PropertySource:代码中指定的配置文件

相同配置项,高优先级覆盖低优先级


Q2:YAML 和 Properties 的区别?

参考答案

特性YAMLProperties
格式缩进敏感key=value
注释##!
结构支持嵌套只能扁平
环境切换--- 分隔-dev 后缀
复杂度简单配置更简洁复杂配置更清晰

选择建议

  • 简单配置 → YAML
  • 需要与 Spring Cloud 集成 → YAML
  • 需要兼容 Java Properties API → Properties

Q3:如何实现配置热更新?

参考答案

方案一:Spring Boot DevTools

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
</dependency>

方案二:Spring Cloud Config + Bus

# 启用 refresh 端点
management:
  endpoints:
    web:
      exposure:
        include: refresh

然后 POST 请求到 /actuator/refresh 触发刷新

方案三:Nacos/Apollo 配置中心

  • 支持 Web UI 修改配置
  • 自动推送到应用并刷新