SpringBoot的基本使用
1、Springboot的基本介绍
SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想,可以让开发人员不必在配置与逻 辑业务之间进行思维的切换,全身心的投入到逻辑业务的代码编写中,从而大大提高了开发的效率,一定程度 上缩短了项目周期。2014 年 4 月,Spring Boot 1.0.0 发布。
在介绍 springboot 时,我们先介绍一下 Spring,Spring是于2003 年兴起的一个轻量级的Java 开源框架,Spring 框架功能很强大,但是就算是一个很简单的项目,我们也要配置很多东西。spring 的缺点:配置繁琐、依赖繁琐。
因此就有了Spring Boot框架,它的作用很简单,就是帮我们自动配置。Spring Boot 以约定大于配置的核心思想,默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。同时它集成了大量常用的第三方库配置(例如 Redis、MongoDB、Jpa、RabbitMQ、Quartz 等等),Spring Boot 应用中这些第三方库几乎可以零配置的开箱即用。
Spring Boot框架的核心就是自动配置,只要存在相应的jar包,Spring就帮我们自动配置。如果默认配置不能满足需求,我们还可以替换掉自动配置类,使用我们自己的配置。另外,Spring Boot还集成了嵌入式的Web服务器,系统监控等很多有用的功,让我们快速构建企业及应用程序。另外SpringBoot通过集成大量的框架使得依赖包的版本冲突,以及引用的不稳定性等问题得到了很好的解决。
Spring Boot的主要优点:
- 为所有Spring开发者更快的入门
- 开箱即用,提供各种默认配置来简化项目配置
- 内嵌式容器简化Web项目
- 没有冗余代码生成和XML配置的要求
Spring Boot 并不是对 Spring 功能上的增强,而是提供了一种快速使用 Spring 的方式。
1.1、SpringBoot的四大特性
- SpringBoot Starter:他将常用的依赖分组进行了整合,将其合并到一个依赖中,这样就可以一次性添加到项目的Maven或Gradle构建中;
- 自动配置:SpringBoot的自动配置特性利用了Spring4对条件化配置的支持,合理地推测应用所需的bean并自动化配置他们;
- 命令行接口:(Command-line-interface, CLI):SpringBoot的CLI发挥了Groovy编程语言的优势,并结合自动配置进一步简化Spring应用的开发;
- Actuatir:它为SpringBoot应用的所有特性构建一个小型的应用程序。但首先,我们快速了解每项特性,更好的体验他们如何简化Spring编程模型。
1.2、使用 Springboot 的好处
回顾我们之前的 SSM 项目,搭建过程还是比较繁琐的,需要:1、配置web.xml,加载spring和spring mvc。2、配置数据库连接、配置spring事务。3、配置加载配置文件的读取,开启注解。。。配置完成之后部署tomcat 调试。
而使用 Spring Boot 来开发项目则只需要非常少的几个配置就可以搭建起来一个 Web 项目,并且利用 IDEA 可以自动生成生成,
2、使用springboot
springboot 对系统的要求:Java 8 & 兼容java14,Maven 3.3+ 。
2.1、基于maven空模板创建springboot项目
下面示例的最终目录结构:
先通过 IDEA 建立一个简单的 maven 工程,不需要使用任何 maven 模板,然后添加依赖:
<?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>org.example</groupId> <artifactId>springbootTest01</artifactId> <version>1.0-SNAPSHOT</version> <!-- 所有的springboot的工程都以spring父工程为父工程 --> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.6.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
建一个 springboot 启动类:
package start; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringbootStartApplication { public static void main(String[] args) { SpringApplication.run(SpringbootStartApplication.class, args); } }
所有的springboot application启动类都需要在类级别上加上@SpringBootApplication注解。
在启动类的当前包或者子包下建一个测试 controller 类:
package start.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class HelloController { @RequestMapping("/hello") public String handle01(){ return "Hello, Spring Boot 2!"; } }
注意,springboot 默认扫描的的类是在启动类当前的包和下级包,所以如果 controller 类不在启动类的当前包或者子包下,则该组件无法被扫描出来。
然后直接执行启动类的 main 方法即可。
在输出日志中可以看到已经启动了内嵌的 tomcat ,并且默认端口号为 8080。
通过访问 http://localhost:8080/hello 可以看到上面接口的输出:
springboot 集成了Tomcat和Jetty,默认使用Tomcat作为应用容器,开发者只需要将工程打成jar包直接丢到服务器上就可以执行了,不需要再单独部署到was、jboss、tomcat这些应用服务器上。
2.2、基于Spring Initializr创建springboot项目
Spring官方提供了非常方便的工具 Spring Initializr 让我们快速构建应用,可以通过 IDEA 或者官网来使用该工具创建springboot项目。
2.2.1、通过 IDEA创建项目
我们可以通过 IDEA 创建 springboot 项目,在创建项目时选择 spring initializr:
然后填写项目基本信息:
在下一步勾选 web,选中 spring web即可:
初始化项目目录结构如下:
通过运行 SpringbootdemoApplication 类的 main 方法即可启动 springboot,然后就可以通过浏览器访问 http://localhost:8080/ 来访问项目了。
有一些无用的文件可以直接删掉,比如 .mvn、mvnw、mvnw.cmd 这些。
有时候通过IDEA创建项目可能比较慢,而且可能连接超时,此时我们可以在官网来创建初始化项目。
2.2.2、通过官网创建项目
我们可以通过访问官方网站来创建一个初始化项目,然后再将该项目拷贝下来进行修改。
- 打开 https://start.spring.io/
- 填写项目信息,记得在右边添加spring web依赖
- 点击”Generate Project“按钮即可生成项目
类似下图:
2.3、打包并运行 springboot项目
参考:https://www.liaoxuefeng.com/wiki/1252599548343744/1282386595676193
3、起步依赖原理
从 springboot 项目中可以看到,所有的 springboot 项目都依赖一个父项目 spring-boot-starter-parent,主要是管理项目的资源过滤及插件。
从该父项目点进去,你会发现该父项目里面还有一个父依赖 spring-boot-dependencies,如下:
再点进去 spring-boot-dependencies,可以看到该项目的管理着的所有依赖的版本,如下:
实际上,这里的 spring-boot-dependencies 才是真正管理 SpringBoot 应用里面所有依赖的版本的地方,是 SpringBoot 的版本控制中心。该项目中的 <dependencyManagement> 标签里定义了各种可能用到的依赖的版本,所以在 springboot 项目里使用这些依赖时默认是不需要写版本,默认会直接使用 spring-boot-dependencies 里面所定义的版本。
比如,springboot 项目里面引入了 spring-boot-starter-web 依赖,如下:
此时,它是不需要写版本的,直接会默认使用 spring-boot-dependencies 里面所定义的版本,我们在 spring-boot-dependencies 里面可以找到 spring-boot-starter-web 依赖的版本号的。
但是需注意,spring-boot-dependencies 中 <dependencyManagement> 标签里定义的依赖是不会被 springboot 项目直接继承的,要想使用这些依赖仍需显式引入,只不过无需写具体版本号而已。
springboot 实际引入的依赖,我们可以在它所引入的 spring-boot-starter-web 依赖中看到,如下在进入到 spring-boot-starter-web 后可以看到所用到的依赖:
4、启动器
springboot-boot-starter-xxx 就是spring-boot的某个场景的启动器。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
如上,spring-boot-starter-web 启动器就帮我们导入了web模块正常运行所依赖的组件。
SpringBoot 将所有的功能场景都抽取出来,做成一个个的 starter (启动器),只需要在项目中引入这些 starter 即可,所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器即可 ;我们未来也可以自己自定义 starter。
5、自定义配置文件
SpringBoot 是基于约定的,所以很多配置都有默认值,Spring Boot在底层已经把所需要的配置都给我们自动配置好了,但如果想使用自己的配置替换默认配置的话,可以使用 application.properties或者application.yml(application.yaml)进行配置。
springboot 配置文件的文件名是固定的:application.properties 或者是 application.yml(后缀也可以写成 yaml),两种文件本质是一样的,区别只是两种文件的语法不同。优先级:application.properties > application.yml > application.yaml,也就是如果相同的配置在三个文件中都存在的话,那就会优先采用 application.properties 中的配置。
-
application.properties
-
语法结构 :key=value
-
application.yml(或者application.yaml)
-
语法结构 :key:空格 value (注意,空格不能去掉,否则无法正确识别)
示例:
下面我们通过配置文件来修改 tomcat 的默认端口,首先在 resource 目录下新建一个 application.properties 文件,然后在该文件下配置 tomcat 的端口号:
然后重新启动启动类即可。由此我们就只能通过 8888 端口来访问接口了。
可以通过参考官网来知道如何通过哪些语法来修改所需配置:https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#application-properties
5.1、读取配置
5.1.1、使用 @Value() 读取配置
我们可以通过 @Value("${属性名}") 的方法来读取配置文件中的配置,该注解会直接将配置文件的该属性值注入到使用该注解的变量中。
(请注意,使用 @Value() 方法给静态变量注入是无效的,如果要给静态变量赋值,可以使用set()方法,参考:https://blog.csdn.net/mononoke111/article/details/81088472)
比如,配置如下:
# application.properties 文件的配置 name=wen person.age=12 address[0]=address0
使用 @Value() 读取配置内容,如下:
@RestController public class HelloController {
@Value("${name}") private String name; @Value("${person.age}") private int age; @Value("${address[0]}") private String address0; @RequestMapping("/hello") public String hello() { System.out.println(name); System.out.println(age); System.out.println(address0); } }
访问 /hello 接口,输出结果如下:
5.1.2、使用Environment读取配置
使用 @Value 读取配置时,需要一个个地写配置属性,在需要读取少量配置时比较方便,当需要读取大量配置时,此时我们可以通过 Evnironment 来读取,就不用一个个地去读取配置了。
如下:
import org.springframework.core.env.Environment; @RestController public class HelloController { @Autowired private Environment env; @RequestMapping("/hello") public String hello() { System.out.println(env.getProperty("name")); System.out.println(env.getProperty("person.age")); System.out.println(env.getProperty("address[0]")); return "hello Spring Boot 222!"; } }
访问 /hello 接口,输出结果如下:
这种方式是依赖注入Evnironment来完成,在成员变量 env 上加上 @Autowired 注解即可完成依赖注入,然后通过使用 env.getProperty("键名") 即可读取出对应的配置的值。
5.1.3、使用@ConfigurationProperties读取配置
使用 @ConfigurationProperties 可以将配置文件中的配置和类中的属性进行绑定,给类中的属性赋值。
比如,配置如下:
# application.properties 配置文件 name=wen address[0]=address0 person.age=12 person.name=personName person.address[0]=beijing person.address[1]=shanghai
定义类,通过 @ConfigurationProperties 注解将配置文件中的值和类中的属性绑定,如下:
//注意别漏了下面的@Component注解 @Component //下面加上prefix参数指定使用配置文件中的哪个对象给person类绑定值,当不指定perfix参数时,默认是使用顶部对象,即整个配置文件中的配置作为一个对象 @ConfigurationProperties(prefix = "person") public class Person { private String name; private int age; private String[] address; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String[] getAddress() { return address; } public void setAddress(String[] address) { this.address = address; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", address=" + Arrays.toString(address) + '}'; } }
然后通过 @Autowired 直接使用该类实例,即可获取到配置文件的属性了。如下:
@RestController public class HelloController { @Autowired private Person person; @RequestMapping("/hello") public String hello() { System.out.println(person); return "hello Spring Boot 222!"; } }
访问 /hello 接口,输出结果如下:
6、profile(指定使用的配置)
profile 可以让 Spring 对不同的环境提供不同配置的功能,可以通过激活、指定参数等方式快速切换环境。 也就是说,不同环境下我们可能有多个不同的配置,profile 可以让我们简单地去切换配置,而不是在部署不同环境时还有手动修改配置这么麻烦。
在实际开发环境中,我们存在开发环境的配置、测试环境的配置、生产环境的配置等等,当里面的配置信息很多时,例如:端口、上下文路径、数据库配置等等,若每次切换环境时,我们都需要进行修改这些配置信息时,会比较麻烦,profile的出现就是为了解决这个问题。
6.1、profile 的配置方式
6.1.1、多个配置文件方式
多个 profile 配置文件时,Spring 官方给出的多个配置文件的命名规则是application-{profile}.properties(.yaml/.yml),也就是 properties 和 yml(yaml)的方式是一样的,只不过最终的语法不太一样而已。
以 properties 作为示例如下:建立三个不同的 properties 文件分别模拟开发、测试、生产不同环境的配置,application-dev.properties、pplication-test.properties、pplication-pro.properties,如下:
内容分别如下:
#application-dev-properties文件内容如下: server.port=8081 #application-test-properties文件内容如下: server.port=8081 #application-pro-properties文件内容如下: server.port=8081
然后我们在 application.properties 中配置实际使用哪个配置文件,比如需要使用 pro 配置文件,如下:
#application.properties文件内容如下,只需通过spring.profiles.active指定使用哪个配置文件的配置即可 spring.profiles.active=pro
配置完后,启动 springboot 项目,可以看到项目端口被配置为 8083,如下:
多个配置文件时,yml(yaml)和 properties 的方式是一样的,只不过语法不太一样而已,yml(yaml)文件中的语法如下:
spring:
profiles:
active: dev
6.1.2、yml多文档方式
使用多个配置文件时,可以建立多个配置文件,然后再通过某个属性配置来指定使用哪个配置文件中的配置。当使用 yml(yaml)作为配置文件时,可以使用单个 yml 多文档的方式来使用 profile。
示例如下,先建立一个 application.yml 文件:
该文件内容如下:
--- server: port: 8081 spring: profiles: dev --- server: port: 8082 spring: profiles: test --- server: port: 8083 spring: profiles: pro --- spring: profiles: active: pro
在 yml 文件中,可以 --- 来划分不同文档区域,每个 --- 下面的配置作为一个单独的文档区域。上面我们在三个不同区域配置了三个不同属性,并且指定了各个区域的 profiles 属性,最后就可以通过 spring.profiles.active 属性来指定使用哪个区域的配置。
配置完后,启动 springboot 项目,可以看到项目端口被配置为 8083,如下:
6.2、profile 的激活方式
有多种方式可以激活 profile,比如上面示例中的在配置文件中指定的方式,另外还有命令行参数、虚拟机参数的方式,其中优先级:命令行参数 > 虚拟机参数 > 配置文件。
6.2.1、配置文件激活profile的方式
在配置文件通过指定 spring.profiles.active 即可激活 profile,比如使用 properties 文件,示例如下:
spring.profiles.active=pro
6.2.2、命令行参数激活profile的方式
通过命令行参数也可以激活 profile。
当通过 jar 包运行 springboot 程序时,可以通过直接在命令后面加参数来指定命令行参数,如下:
java –jar xxxxxx.jar --spring.profiles.active=pro
当使用 idea 集成环境时,可以直接在工具中配置命令行参数,如下:
6.2.3、虚拟机参数激活profile的方式
也可以通过指定虚拟机参数的方式来激活 profile。比如使用 idea 时,配置如下:
通过配置 -Dspring.profiles.active=dev 来指定使用哪个配置。
7、配置文件加载顺序
7.1、内部配置加载顺序
Springboot 程序启动时,会从以下位置查找配置文件并加载:
- 当前项目根目录下的/config目录下
- f当前项目的根目录下
- classpath:/config/:classpath的/config目录(即resource目录下的config目录)
- classpath:/ :classpath的根目录(即resource目录下)
配置文件加载优先级为由上至下,上面的优先级更高,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容。
假设项目如下,一个项目内有多个模块,则配置文件优先级分别如下:
上面四个配置文件都会被加载,但是如果配置相同,则优先级高的配置文件的配置会被选中使用。
7.2、外部配置文件加载顺序
外部配置文件,即不放在项目内的配置文件。在启动项目时,可以通过命令行参数的方式来指定外部的配置文件作为优先级更高的配置文件。如下:
java –jar xxxxxx.jar --spring.config.additional-location="D:/xxx/application.properties"
此时指定的配置文件和默认加载的内部配置文件共同起作用形成互补配置,指定的配置文件的优先级更高。
或者我们可以在打出的 jar 包的相同目录下新建一个 config 目录,在该目录下新建 application.properties 文件,则使用 java -jar 命令运行 springboot 项目时,无需指定配置文件,也会自动加载该目录下的配置文件。
如下:
在打出的 jar 包的同级目录下新建 config 目录,在该目录下建立配置文件,此时启动 jar 包无需指定配置文件也会自动加载 config 目录下的配置文件作为优先级更高的配置。
java –jar xxxxxx.jar --spring.config.additional-location="D:/xxx/application.properties"
8、springboot项目放置静态资源
一个新建的 springboot 项目的目录结构如下:
SpringBoot对于静态资源放置的位置是有规定的,springboot 默认提供两个目录给我们存放静态资源:
- 一个是 src/mian/resource目录(上面将的就是这种情况)
- 一个是 ServletContext 根目录下,也就是 src/main/webapp
8.1、在resources存放静态资源
在 src/main/resources 目录下,SpringBoot 提供了几个默认的存放路径来给我们存放静态资源:
"classpath:/META-INF/resources/" "classpath:/resources/" "classpath:/static/" "classpath:/public/"
通俗来讲classpath对应的项目中 src/main/resources 目录。所以上面的路径,比如如:“classpath: static/” 指的就是 src/main/resources/static 目录。
所以说,我们可以在 springboot 项目的 src/main/resources/META-INF/resources、src/main/resources/public、src/main/resources/resources、src/main/resources/static 目录下存放静态资源。
如下,除了 5.jpg ,其他资源都可以通过 http://ip/项目上下文/静态资源名 来直接访问静态资源
8.2、在 src/main/webapp 下存放静态资源
一般创建的 maven 项目里面都没有 webapp 文件夹,我们可以自己在 src/main 目录下创建一个 webapp 目录,然后在该目录下存放各种静态资源,就可以直接访问静态资源了。
8.3、自定义静态资源路径
我们也可以自己通过配置文件来指定静态资源的存放路径,在application.properties中配置。示例如下:
spring.resources.static-locations=classpath:/mystatic/,classpath:/myresources/
一旦自己定义了静态文件夹的路径,原来的自动配置就都会失效了。
9、JSR303(数据校验)
JSR是Java Specification Requests的缩写,意思是Java 规范提案。JSR已成为Java界的一个重要标准。
Bean Validation 中内置的 constraint:
Hibernate Validator 附加的 constraint:
使用可参考:https://blog.csdn.net/Young_Naive/article/details/113174827
9.1、使用数据校验
Springboot中可以用@validated来校验数据,如果数据异常则会统一抛出异常,方便异常中心统一处理。
我们这里来写个注解让我们的name只能支持Email格式
@Component //注册bean @ConfigurationProperties(prefix = "person") @Validated //数据校验 public class Person { @Email(message="邮箱格式错误") //name必须是邮箱格式,否则将会 private String name; }