@
约定优于配置(Convention over Configuration / CoC),又称约定编程,是一种软件设计规范,本质上是对系统,类库或框架中一些东西。
一个大众化合理的默认值(缺省值)
2. 例如在模型中存在一个名为User的类,那么对应到数据库会存在一个名为 user 的表,只有偏离这个约定时才需要做相关的配置(例如
你想将表名命名为:t_user等非user时才需要写关于这个名字的配置)
3. 简单来说就是假如你所期待的配置 与 约定的配置 一致,那么就可以不做任何配置,约定不符合期待时,才需要对约定进行替换配置。
4. 约定优于配置:为什么要搞一个“约定优于配置”
约定其实就是一个规范,遵循了规范,那么就存在通用性。存在了通用性,那么事情就会变得相对简单 ,程序员之间的沟通成本就会降低,工作效率会提升,合作也会变得更加简单。
5. 生活中,这样的情况,大量存在:比如:两个都是男生,你说一起去上厕所去,那么,他们两个人都是(默认,约定好的都是去男生厕所,而特意说明是:去女生厕所。)
6. 注意:误区:默认是采用约定的,但是你配置了,还是采用你的配置的信息的。
spring-boot-starter-parent 还有父项目,声明了开发中常用的依赖的版本号
并且进行 自动版本仲裁 ,即如果程序员没有指定某个 依赖的 jar
的版本,则以父项目指定的版本为准。
如果 Spring Boot 当中默认配置的 jar
依赖的版本,不是,我们所想要的该如何配置修改成我们自己想要的呢。
如何修改 Spring Boot 当中对应 jar。
演示: 将 SpringBoot mysql 驱动修改成 5.1.49 版本的。
首先,我们先要学会如何查看到对应我们所需的 jar
在 Spring Boot 的默认配置当中使用的是什么版本的。
在spring-boot-dependencies\2.5.3\spring-boot-dependencies-2.5.3.pom,中我们可以找到对应的
jar
包的依赖版本,如下图所示:这里 Spring Boot 对于 MySQL 的依赖默认配置是8.0.26
的
查 看 spring-boot-dependencies.pom 里 面 规 定 当前 依 赖 的 版 本 对 应 的 key , 这 里 是 mysql.version
修改 Spring Boot 当中对应 jar;有两种方式:
pom.xml
文件当中直接导入,自己想要的 jar
的版本即可。jar
信息和 jar的版本
信息分开来编写的了”。方式一: 修改 pom.xml 重写配置 当更新 Maven 时,就依赖到新的 ,mysql 驱动。
直接导入我们自己想要的 依赖的jar
的配置,然后,更新 Maven 即可。
<!-- 自定义设置:1 我们自己指定mysql/驱动版本-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version> <!--不指明就是,采用SpringBoot 约定好的(也就是默认的8.26)-->
</dependency>
然后,我们在刷新 Maven,重新加载 jar
注意: 如果配置的依赖
jar
包时,不指明就是version 版本的话,就会采用 SpringBoot 约定好的(也就是默认的8.26)版本的。如下:我们将指明的版本的 version 注释掉,再次更新,看看。
完整的 pom.xml
信息。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.rainbowsea</groupId>
<artifactId>quickstartBlog</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 导入 springboot 父工程,规定的写法 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
</parent>
<!-- 导入 web 项目场景启动器,会自动导入和 web 开发相关依赖,非常方便 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 自定义设置:1 我们自己指定mysql/驱动版本-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version> <!--不指明就是,采用SpringBoot 约定好的(也就是默认的8.26)-->
</dependency>
</dependencies>
</project>
方式二: 将依赖jar
包的配置信息,和配置版本分开来编写。
在
<properties>
标签中,配置 jar 的版本信息 ,可以配置多个不同的 jar 的版本信息。在
<dependencies>
标签中,配置 jar 的 配置坐标信息 ,可以配置多个 jar
<properties>
<mysql.version>5.1.49</mysql.version>
</properties>
<!-- 导入 web 项目场景启动器,会自动导入和 web 开发相关依赖,非常方便 -->
<dependencies>
<!-- 自定义设置:1 我们自己指定mysql/驱动版本-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
更新 Maven ,重新加载 jar 。
完整的 pom.xml
信息。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.rainbowsea</groupId>
<artifactId>quickstartBlog</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 导入 springboot 父工程,规定的写法 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.3</version>
</parent>
<properties>
<mysql.version>5.1.49</mysql.version>
</properties>
<!-- 导入 web 项目场景启动器,会自动导入和 web 开发相关依赖,非常方便 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 自定义设置:1 我们自己指定mysql/驱动版本-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
</project>
开发中我们引入了相关场景的 starter,这个场景中所有的相关依赖都引入进来了,比如:我们之前学习到的 web 开发引入了,该 starter 将导入与 web 开发相关的所有包。
依赖树 : 可以看到 spring-boot-starter-web ,帮我们引入了 spring-web mvc,spring-web 开发模块,还引入了 spring-boot-starter-tomcat 场景,spring-boot-starter-json 场景,这些场景下面又引入了一大堆相关的包,这些依赖项可以快速启动和运行一个项目,提高开发效率.
所有场景启动器最基本的依赖就是 spring-boot-starter
, 前面的依赖树分析可以看到,
这个依赖也就是 SpringBoot 自动配置的核心依赖
Spring Boot 官方提供的 starter 场景启动器的介绍说明:https://docs.spring.io/spring-boot/reference/using/build-systems.html#using.build-systems.starters 。
意思就是说:在开发中我们经常会用到 spring-boot-starter-xxx ,比如 spring-boot-starter-web,该场 景是用作 web 开发,也就是说 xxx 是某种开发场景。
这时候,我们只要引入 starter,这个场景的所有常规需要的依赖我们都自动引入。
Spring Boot3 支持的所有场景如下:官方地址:https://docs.spring.io/spring-boot/reference/using/build-systems.html#using.build-systems.starters
Spring Boot 也支持第三方starter。
第三方starter不要从spring-boot 开始,因为这是官方spring-boot保留的命名方式的。
第三方启动程序通常以项目名称开头,例如:名“XXx”的第三方启动程序项目通常被命名为:“XXx-spring-boot-stater”。
也就是说:xxx-spring-boot-starter是第三方为我们提供的简化开发的场景启动器
我们是否还记得,前面学习SSM整合时,需要配置 Tomcat ,配置 Spring MVC,以及配置如何扫描包,配置字符过滤器,配置视图解析器,文件上传等 ✏️✏️✏️ SSM 整合(Spring + MyBatis;Spring + Spring MVC)-CSDN博客 。非常麻烦。而在 Spring Boot 中,存在自动配置 机制,提高开发效率。
简单回顾以前 SSM 整合的配置:
我们可以通过获取到的 ioc 容器,查看容器创建的组件来验证。
package com.rainbowsea.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
// @SpringBootApplication 表示是一个 springboot 应用
@SpringBootApplication
public class MainApp {
public static void main(String[] args) {
// 启动 SpringBoot 应用程序
ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);
// 查看容器里面的组件
String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println("beanDefinitionName ---" + beanDefinitionName);
}
}
}
更加直接查看的方式:我们可以通过 Debug 的方式,在 ioc 打上断点,从而查看 ioc 容器中有哪些 Bean 对象被创建了。
在Spring Boot 的自动配置中,我们不需要像Spring MVC 中一定要配置扫描包 。Spring Boot 有默认的扫描包结构。
如下是来自 Spring Boot 官方文档说明 【https://docs.spring.io/spring-boot/reference/using/structuring-your-code.html#using.structuring-your-code.using-the-default-package】的:自动扫描的包结构。你按照该“约定/自动扫描包结构”,开发项目,就不需要配置扫描包了,直接用 Spring Boot 约定的/默认的即可。
com
+- example
+- myapplication
+- MyApplication.java
|
+- customer
| +- Customer.java
| +- CustomerController.java
| +- CustomerService.java
| +- CustomerRepository.java
|
+- order
+- Order.java
+- OrderController.java
+- OrderService.java
+- OrderRepository.java
演示: 要求能扫描 com.rainbowsea 包下的 HiController.java 应该如何处理 ?
首先我们先测试一下,不按照 Spring Boot 默认的包结构创建的,主程序类。会怎么样。
在 quickstartBlog\src\main\java\com\rainbowsea\目录/包下创建一个,名为 HiController.java主程序类。 并测试, 这时是访问不到的。
运行主程序,打开浏览器输入:http://localhost:8080/hi 测试。
原因是:hello 配置的 HelloController 是在 Spring Boot 的默认自动配置的包结构下的,而我们的 hi 配置的 HiController 并不是在,Spring Boot 的自动配置打包结构下的,而我们自己有没有配置包扫描,Spring Boot 自然找不到了。
上面我们测试了,在 com.rianbowsea 包下的 HiController.java 是扫描不到了,扫描不到,也就无法加入到 ioc 容器当中被 Spring Boot管理起来了,也就无法被访问到了。
所以想要,让 HiController.java 可以被扫描到,就解决了这个,无法访问找不到的问题了。
方法:
我们修改 MainApp.java, 增加扫描的包 。
使用 @SpringBootApplication
注解当中的 scanBasePackages
注解属性,该属性的值:就是让Spring Boot 扫描的,包路径。
package com.rainbowsea.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
// @SpringBootApplication 表示是一个 springboot 应用
// 直接在 SpringBootApplication 注解后指定,让 Spring Boot 要扫描到的包路径
@SpringBootApplication(scanBasePackages = {"com.rainbowsea"})
public class MainApp {
public static void main(String[] args) {
// 启动 SpringBoot 应用程序
ConfigurableApplicationContext ioc = SpringApplication.run(MainApp.class, args);
// 查看容器里面的组件
String[] beanDefinitionNames = ioc.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println("beanDefinitionName ---" + beanDefinitionName);
}
}
}
配置好之后,我们再次重启 ,运行试试。
SpringBoot 项目最重要也是最核心的配置文件就是 application.properties,所有的框架配 置都可以在这个配置文件中说明 :Spring Boot 框架中配置文件 application.properties 当中的所有配置大全-CSDN博客
在Spring Boot中各种配置都有默认,而想要修改配置的话, 可 以 在 resources\application.properties文件中修改。至于application.properties
文件是需要我们手动创建的。
特别注意:该文件名必须是
application.properties
,后缀也不可以修改。强烈建议将其放到 类的根路径下(也就是resources
目录下 )其次是,注意:在
.properties
后缀的配置文件,当中编写,不要有空格,尽量不要有空格。
如下:
编写配置:设置修改 Server 的监听窗口为 9090
# 修改server的监听窗口为 9090
# Tomcat started on port(s): 9090 (http) with context path ''
server.port=9090
编写配置好后,运行主程序,重新加载程序,看看。
# 修改server的监听窗口为 9090
# Tomcat started on port(s): 9090 (http) with context path ''
server.port=9090
# 修改文件上传的大小
# 解读一下这个配置是在哪里读取!
#multipart.max-file-size,属性可以指定SpringBoot 上传文件的大小限制(体现“约定优于配置”)
# 默认骗子hi最总都是映射到某个类上,比如:multipart.max-file-size
# 会映射/关联到MultipartProperties 类
# 把光标放在该属性,输入 ctrl + b,或者是按住 ctrl + 点击,就可以定位这个属性是管理到哪个类(属性)
spring.servlet.multipart.max-file-size=10MB
这里,我们想要看到效果的话,需要Debug,打上断点,进行 Debug 调试才可以比较清除的看到效果。
# 修改server的监听窗口为 9090
# Tomcat started on port(s): 9090 (http) with context path ''
server.port=9090
# 修改文件上传的大小
# 解读一下这个配置是在哪里读取!
#multipart.max-file-size,属性可以指定SpringBoot 上传文件的大小限制(体现“约定优于配置”)
# 默认骗子hi最总都是映射到某个类上,比如:multipart.max-file-size
# 会映射/关联到MultipartProperties 类
# 把光标放在该属性,输入 ctrl + b,或者是按住 ctrl + 点击,就可以定位这个属性是管理到哪个类(属性)
spring.servlet.multipart.max-file-size=10MB
# 配置开始的项目根的映射路径
server.servlet.context-path=/rainbowsea
重新启动程序,测试:
特别说明:讲解
上述的配置文件时在哪里读取的
比如:multipart.max-file-size,属性可以指定SpringBoot 上传文件的大小限制(体现“约定优于配置”)
默认 Spring Boot 都会将其映射到某个类上,比如:multipart.max-file-size,会映射/关联到MultipartProperties 类。配置都会被映射到相对应的类上的。
而我们将光标放在该属性,输入 ctrl + b,或者是按住 ctrl + 点击,就可以定位这个属性是管理到哪个类(属性)
在 Spring Boot 中,我们还可以还在 .properties
文件中自定义配置,通过 @Value("${}")
的方式来获取对应属性值。
# 修改server的监听窗口为 9090
# Tomcat started on port(s): 9090 (http) with context path ''
server.port=9090
# 修改文件上传的大小
# 解读一下这个配置是在哪里读取!
#multipart.max-file-size,属性可以指定SpringBoot 上传文件的大小限制(体现“约定优于配置”)
# 默认骗子hi最总都是映射到某个类上,比如:multipart.max-file-size
# 会映射/关联到MultipartProperties 类
# 把光标放在该属性,输入 ctrl + b,或者是按住 ctrl + 点击,就可以定位这个属性是管理到哪个类(属性)
spring.servlet.multipart.max-file-size=10MB
# 配置开始的项目根的映射路径
server.servlet.context-path=/rainbowsea
# 自定义配置属性
my.website=https://www.baidu.com
package com.rainbowsea;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller // 注入到 ioc 容器当中
public class HiController {
@RequestMapping("/hi") // 设置请求映射路径
@ResponseBody // 表示返回的是一个 json/字符串,而不是一个网页
public String hi(){
System.out.println("website" + website);
return "hi~, spring boot";
}
// 需求website,属性值从application.properties 的 k-v
@Value("${my.website}")
private String website;
}
运行测试:
当然,我们也时可以 将其 配置到 Bean 对象上的,只不过,配置到 Bean 对象上的话,有更好的方式,可以用 Spring Boot 的容器管理。
打开 ConfigFileApplicationListener.java , 看一下源码;
// 指明: application.properties 可以存放的位置在哪里,Spring Boot 可以成功读取到
private static final String DEFAULT_SEARCH_LOCATIONS = "classpath:/,classpath:/config/,file:./,file:./config/*/,file:./config/";
// 指明: 配置类,要是为:application,
private static final String DEFAULT_NAMES = "application";
自动配置遵守按需加载原则:也就是说,引入了哪个场景 starter启动器
就会加载该场景关联,的 jar 包,没有引入的 starter 则不会加载其关联 jar 。
SpringBoot 所有的自动配置功能都在 spring-boot-autoconfigure 包里面;
在Spring Boot 中的自动配置包,一般是 XXxAutoConfiguration.java 对应 XXxProperties.java,如图
pom.xml
文件当中直接导入,自己想要的 jar
的版本即可。jar
信息和 jar的版本
信息分开来编写的了”。application.properties
的理解和使用。 application.properties
的每个配置属性,都对应这 Spring Boot 当中的某个类当中的某个属性,并且加入到了 ioc 容器当中。“在这个最后的篇章中,我要表达我对每一位读者的感激之情。你们的关注和回复是我创作的动力源泉,我从你们身上吸取了无尽的灵感与勇气。我会将你们的鼓励留在心底,继续在其他的领域奋斗。感谢你们,我们总会在某个时刻再次相遇。”