JAVASpring

谈谈 SpringBoot 约定大于配置

“约定大于配置”(Convention Over Configuration,简称 CoC)是一种软件开发哲学,它的核心思想是:通过预设的 “约定”(即通用的规则或默认行为)来减少不必要的配置工作,让开发者专注于业务逻辑而非基础设施

背景


Spring Boot 的核心优势之一就是 “约定大于配置”(Convention Over Configuration),它通过自动化配置和 Starter 依赖机制,帮开发者省去了传统 Spring 项目中大量繁琐的配置工作,实现 “零配置启动”。以下是具体解释:

在 Spring Boot 之前,搭建一个完整的 Spring 项目需要:

手动配置 XML 或 Java Config

  • 配置 DispatcherServlet、组件扫描路径、事务管理器、数据源等。
  • 示例(XML 配置):
<context:component-scan base-package="com.example.demo" />
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://localhost:3306/mydb" />
</bean>

管理依赖地狱

  • 需要精确匹配各组件版本(如 Spring、Hibernate、Jackson),版本冲突常见。
  • 例如,引入 Spring MVC 时,需手动添加 servlet-api、jackson-databind 等依赖。

部署复杂

  • 需要外部 Tomcat/Jetty 服务器,配置 Web.xml 或 Servlet 初始化类。

一、通俗类比:像 “住酒店” 而不是 “盖房子”


传统开发(配置地狱):

  • 就像 “自己盖房子”:
    你需要决定每一个细节 —— 墙刷什么颜色、插座装在哪里、马桶选什么型号…… 即使大部分需求和别人一样,也得从头设计。
  • 示例:在传统 Spring 中,配置数据源需要写几十行 XML 或 Java Config,即使 90% 的项目配置都是相似的。

约定大于配置(Spring Boot):

  • 就像 “住酒店”:
    酒店已经按标准布置好房间(床、浴室、空调),你只需入住即可。如果有特殊需求(如加张床),再单独提出(少量配置)。
  • 示例:Spring Boot 默认配置好数据源、Web 服务器等,你只需在 application.properties 中改几个参数(如数据库 URL)。

 

二、Spring Boot 中的具体体现


1. 目录结构约定

Spring Boot 默认遵循特定的目录结构,无需额外配置:

  • src/main/java:Java 代码
  • src/main/resources:配置文件(application.properties、static/、templates/)
  • src/test/java:测试代码
src/main/java/         # Java 代码
  com/example/demo/    # 主包路径
    DemoApplication.java  # 主应用类
    
src/main/resources/    # 资源文件
  application.properties # 配置文件
  static/              # 静态资源(CSS/JS/图片)
  templates/           # 模板文件(Thymeleaf)
  
src/test/java/         # 测试代码

好处:无需配置组件扫描路径,Spring Boot 自动从 DemoApplication 所在包开始扫描。

 

2. 自动配置

Spring Boot 根据类路径中的依赖自动配置 Bean:

  • 示例
    若引入 spring-boot-starter-web,则自动配置:
    • 嵌入式 Tomcat 服务器
    • DispatcherServlet(Spring MVC 的核心)
    • JSON 序列化 / 反序列化(Jackson)
    • 默认错误处理页面
    无需手动配置,直接写 Controller 即可:
@RestController
public class HelloController {
    @GetMapping("/")
    public String hello() {
        return "Hello, Spring Boot!";
    }
}

 

3. 默认属性值

Spring Boot 为几乎所有配置项提供默认值,你只需覆盖需要修改的部分。

# application.properties(只需配置与默认值不同的部分)
server.port=8081        # 默认是 8080
spring.datasource.url=jdbc:mysql://localhost/mydb

 

4. Starter 依赖

Starter 是一组预定义的依赖集合,避免手动管理版本冲突。

<!-- 添加 Web 功能只需这一行 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Starter 会自动引入:

  • spring-webmvc
  • tomcat-embed-core
  • spring-boot-starter-json
  • … 以及它们的兼容版本。

常用 Starter:

<!-- Web 应用 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- JPA 数据访问 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- 测试 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

 

5.嵌入式服务器

Spring Boot 内置 Tomcat、Jetty 或 Undertow,无需部署 WAR 文件,直接通过 java -jar 运行。

# 只需在 application.properties 中指定端口
server.port=8081

三、为什么要遵循约定?


  1. 提高开发效率
    • 减少重复配置,专注业务逻辑。
    • 例如:传统 Spring 配置数据库需要 20 行代码,Spring Boot 只需 3 行(URL、用户名、密码)。
  2. 降低学习成本
    • 新开发者无需记忆复杂配置,遵循约定即可。
    • 例如:所有 Spring Boot 项目的启动方式都是 SpringApplication.run()
  3. 代码一致性
    • 团队项目结构统一,便于协作和维护。
    • 例如:所有组件都按约定放在 controller/service/repository/ 包下。
  4. 减少错误
    • 自动配置减少人为配置错误(如版本不兼容、Bean 命名冲突)。

 

四、何时需要打破约定?


约定并非强制,当默认行为无法满足需求时,可以:

  1. 覆盖默认配置
    • 例如:修改默认端口、自定义错误处理器。
# application.properties
server.port=8081
  1. 禁用自动配置
    • 例如:禁用默认的数据源,使用自定义配置。
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class MyApp { ... }
  1. 自定义 Starter
    • 为团队或项目创建专用的 Starter,封装特定业务的约定。

 

五、其他领域的 “约定大于配置”

  • Maven 项目结构
src/main/java/     # 源代码
src/main/resources/ # 资源文件
src/test/java/     # 测试代码

无需配置编译器和测试运行器的路径。

 

  • REST API 设计

约定 URL 路径和 HTTP 方法:

GET /users        # 获取用户列表
POST /users       # 创建用户
GET /users/{id}   # 获取单个用户

减少文档和沟通成本。

 

  • 数据库迁移工具(Flyway/Liquibase)

约定 SQL 文件命名规则:

V1__Initial_Setup.sql
V2__Add_User_Table.sql

自动按版本号执行迁移。

 

六、总结


“约定大于配置” 是一种平衡效率与灵活性的哲学

  • 默认情况下:遵循约定,快速搭建项目;
  • 需要定制时:通过少量配置覆盖默认行为。

Spring Boot 通过这种方式,将传统 Spring 项目的配置工作量从 “天” 级降低到 “分钟” 级,让开发者真正专注于 “写业务代码” 而非 “搭基础设施”。这也是 Spring Boot 成为 Java 企业级开发首选框架的核心原因之一。编辑分享