如何理解 Spring Boot 中的约定优于配置

6,214 阅读4分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

维基百科解释

维基百科解释如下:

约定优于配置(convention over configuration),也称作按约定编程,是一种软件设计范式,旨在减少软件开发人员需做出决定的数量,活得简单的好处,而又不失灵活性。

本质上是说,开发人员仅需要规定应用中不符约定的部分,例如,如果模型中有个名为 Sale 的类,那么数据库中对应的表就会默认命名为 sales。只有偏离这一约定时,例如将该表命名为“products_sold”,才需写有关这个名字的配置。

如果您所用工具的约定与你的期望相符,便可省去配置;反之,你可以配置来达到你所期待的方式。

个人理解

约定优于配置,并不是零配置或者完全没有配置,而是通过约定来减少配置。

约定优于配置,并不是一个新套路,新技术,新思想,而是原来就一直存在的, Spring Boot 只不过是把它放大了,并真正的做到了约定优于配置。

例如,在 Spring Boot 中,当我们导入一个 spring-boot-starter-web 后,就会自动的帮我们导入 Spring MVC 的相关依赖(包括 Json 支持的 Jackson 和数据校验的 Hibernate Validator)和一个内置的 Tomcat 容器,这使得在开发阶段可以直接通过 main 方法或是 JAR 包独立运行一个 Web 项目。

Spring Boot 约定,当你导入 spring-boot-starter-web 后,就约定了你是一个 web 开发环境,当你是一个 web 环境,就约定了你会使用 Spring MVC(Struts2 之类的就拜拜了,因为不是亲生的,而且确实没 Spring MVC使用率高)至于其它的也约定你会需要,都给你默认导入进来,当你觉得不合适的时候,可以用更少的改动,满足你的需要。

Spring 在推动“约定优于配置”这一设计理念,从 Spring 的注解版本(JDK5.0发布,采用元数据,引入注解的概念)就已经开始了。引入注解就是为了减少一些默认配置,引入注解也就代表着简化配置的开始,官方说基于 spring 的基础就是这个事实。

SpringBoot 约定以 starter 的形式减少依赖,于是相继推出了不少常用的 starter。

Spring Boot 中如何体现

运行方式

spring-boot-starter-web 包含了 Spring MVC 的相关依赖(包括 Json 支持的 Jackson 和数据校验的 Hibernate Validator)和一个内置的 Tomcat 容器,这使得在开发阶段可以直接通过 main 方法或是 JAR 包独立运行一个 WEB 项目。而在部署阶段也可以打成 WAR 包放到生产环境上运行。


import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication

public class StorageApplication {

    public static void main(String[] args) {

        SpringApplication.run(StorageApplication.class, args);

    }

}

在拥有 @SpringBootApplication 注解的类中,使用 SpringApplicationrun 方法可以通过 JAR 移动项目。

继承 SpringBootServletInitializer 类并实现 configure 方法,使用 applicationsources 方法可以通过 WAR 启动项目。

配置文件

Spring Boot 的配置文件必须是,也只能是 application. 命名的 yml 文件或者 properties 文件,且唯一。

Spring Boot 默认只会去 src-main-resources 文件夹下去找 application 配置文件。

配置文件中可以定义一个叫做 spring.profiles.active 的属性,该属性可以根据不同的运行环境读取不同的配置文件。例如将该属性定义为 dev 的话,Spring Boot会额外从 application-dev.yml 配置文件中读取该环境的配置。

Spring Boot 注入配置文件属性的方法有两种,一种是通过 @Value 注解接受配置化文件中的属性,另外一种使用过 @ConfigurationProperties 注解通过 set 方法自动为 Bean 注入对应的属性。

  1. 通过 @Value 注入属性,接收者既可以是方法参数,也可以是成员变量,例如:

/**

* elasticsearch的地址

*/

@Value("${elasticsearch.host}")

private String host;

  1. 通过 @ConfigurationProperties 读取配置初始化 Bean,会直接调用对应的 set 方法注入:

@Bean(name = "account")

@ConfigurationProperties(prefix = "spring.datasource.account")

public DataSource accountDbDataSource() {

    return DataSourceBuilder.create().build();

}

DataSource

如果使用了 Spring-boot-starter-data-jpa,Spring Boot 将会自动创建一个 DataSource Bean。可以直接在配置文件中定义它的属性,前缀是 Spring.datasource。并且无需指定数据库的方言,这个 Bean 会自动根据项目总依赖的的数据库驱动判断使用的是哪种数据库。

同样的,如果使用了 spring-boot-starter-data-redis,也会自动创建 RedisTemleteConnectionFactory 等 Bean。也同样可以在配置文件中定义属性,前缀是 spring.redis

参考文档