SpringBoot2
什么是SpringBoot
Spring Boot 是Spring 家族中的一个全新框架,它用来简化 Spring 应用程序的创建和开发过程,也可以说,SpringBoot能简化我们之前采用 SpringMvc + Spring + MyBatis 框架进行开发的过程。
以往我们采用SpringMvc + spring + Mybatis 框架进行开发的时候,搭建和整合三大框架,我们需要做很多工作,比如配置web.xml。配置Spring,配置MyBatis,并将它们整合到一起,而Spring Boot框架对此开发进行了革命性的颠覆,完全抛弃了繁琐的XML配置,采用大量的默认配置简化我们的开发过程。
所以采用SpringBoot可以非常容易和快速的创建基于Spring框架的应用程序, 让他编码变简单了,配置变简单了,部署变得简单了,监控变得简单了,正因为SpringBoot 它化繁为简,让开发变得极其简单和快捷,所以在业界备受关注。
SpringBoot的特性
- 能够快速创建基于Spring的应用程序
- 能够直接使用 Java Main方法启动内嵌的Tomcat服务器运行SpringBoot程序,不需要部署 war 包文件。
- 提供约定的 starter POM 来简化 Maven 配置,让Maven的配置变得简单
- 自动化配置,根据项目的Maven 依赖配置,SpringBoot 自动配置 Spring,SpringMvc,等
- 提供了程序的健康检查等功能。
- 基本可以完全不适用XML配置文件,采用注解配置。
SpringBoot四大核心内容
- 自动配置
- 起步依赖
- Actuator
- 命令行界面
创建第一个SpringBoot-Web工程
我们直接使用Idea,创建SpringBoot工程。我们新建一个工程。
我们选择左侧的Spring Initializr, 然后项目名称为 SpringBoot2,类型是一个Maven来管理的项目。然后打包为Jar包。
这里我们选择Java8。最稳定的版本。yyds。
在 1处标记,表示了我们的SpringBoot的版本,这里我用的是一个2.5.2的版本。
在2处标记,表示了可以添加的模块,我们点开Web模块,把SpringWeb这个模块,添加到我们的项目中。
在3标记处,表示了我们已经添加的模块。
然后我们点击FINISH,表示完成模块的添加,然后进行下一步,开始创建项目。静等完成即可。
目录结构详解
这是我们创建完成后的一个目录结构。
在这个项目的目录结构中, 存在这样的几个目录。 (.mvn mvnw mvnw.cmd) 其实但看 mvnw.cmd 就可以看出来,这是命令行所需要的东西。但是在我们国内。是基本上完全用不到的,这是可有可无的,你可以把它做一个删除的操作。当然,你也可以不用管他。看你自己的心情。
SpringBoot2.iml,这个不用多说,每一个Idea工程都会有一个对应的iml文件,这是我们Idea工具生成的文件。
.gitignore, 版本控制器提交的时候,所要忽略的一些文件。在这个文件里会有一些内容,有兴趣的可以看看。
HELP.md ,md是一个标记语言,也就是富文本吧。对我们没啥用,做了一些没啥用的描述。
剩下的src里面的内容,就是我们的核心内容了。pom.xml 是我们的maven项目依赖管理,也就是说,在以后我们去提交项目的时候,只需要给别人Src目录下的全部内容,和pom.xml文件,即可。
在我们打开Src目录后,里面有一个main和test文件夹。test不用多说,用来测试,主要看main文件夹下的内容,展开main文件夹,有一个Java和一个resources, Java主要用来写我们的Java代码,resources,用来存放一些配置文件。
但是在生成项目的时候,还额外生成了两个类,分别存放在test文件夹和java文件夹下。SpringBoot2Application,SpringBoot2ApplicationTests
我们打开 SpringBoot2Application这个类。
package com.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBoot2Application {
public static void main(String[] args) {
SpringApplication.run(SpringBoot2Application.class, args);
}
}
这个类,叫做启动入口类。这就是Spring工程的一个启动入口类。这个入口类的名称是固定死的吗? 其实并不是,名称并不能决定一个类是否是一个启动类。我们要把目标放在类上的注解。
@SpringBootApplication
我们点进去@SpringBootApplication 这个注解。
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.boot.autoconfigure;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.context.TypeExcludeFilter;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.core.annotation.AliasFor;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@AliasFor(
annotation = EnableAutoConfiguration.class
)
Class<?>[] exclude() default {};
@AliasFor(
annotation = EnableAutoConfiguration.class
)
String[] excludeName() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackages"
)
String[] scanBasePackages() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "basePackageClasses"
)
Class<?>[] scanBasePackageClasses() default {};
@AliasFor(
annotation = ComponentScan.class,
attribute = "nameGenerator"
)
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
@AliasFor(
annotation = Configuration.class
)
boolean proxyBeanMethods() default true;
}
我们并不是看它是怎么实现的,我们也不分析源码,我们只看这个类上标明了哪一些注解。主要有三个。
- @SpringBootConfiguration
- 当我们使用*@SpringBootConfiguration标记一个类时,这意味着该类提供了@Bean*定义方法。 Spring容器处理配置类以为我们的应用实例化和配置bean。
- @EnableAutoConfiguration
- 开启自动装配
- @ComponentScan
- 开启扫描器
我们并不会详细解释。只是让你暂时知道,这个@SpringBootApplication这个类,做了什么。
我们继续往下看resources这个文件夹。里面有两个文件夹,static(静态),templates(模板),static放的是一些静态资源文件,img啊,css啊,js啊等一些文件。而这个static文件夹的名称,是固定的,templates也是。
application.properties 是SpringBoot核心配置文件,只有一个。它的名字也只能叫做application。不能叫做别的。他不是xml文件,是properties,里面写的数据是key:value。
解读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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>SpringBoot2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBoot2</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
首先,4.0.0 这是一个固定的值,我们不需要改,除非哪一天maven开发者说,我们换一个吧。我们才需要做出对应的更改。这是不动的。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
parent 指向父工程,这里指向了它的父工程Jav坐标。 我们不需要,你不想要也可以删除。
<groupId>com.example</groupId>
<artifactId>SpringBoot2</artifactId>
<version>0.0.1-SNAPSHOT</version>
这里是我们的工程的JAV坐标。
<name>SpringBoot2</name>
<description>Demo project for Spring Boot</description>
我们创建过程中,描述的一个内容。这个你也可以不要。把它做一个删除操作。
<properties>
<java.version>1.8</java.version>
</properties>
Java的版本号
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
spring-boot-starter-web 是我们SpringBoot框架Web项目起步依赖。
spring-boot-starter-test 是我们SpringBoot框架测试起步依赖。但是这个东西我们一般都不用,就可以把它删除掉。看你心情。
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
这是SpringBoot编译打包的一个插件。也是必不可少的一个插件。
配置文件
修改默认端口号和上下文根
之前我们也说过,核心配置文件,只能叫做application。并且核心配置文件只能有一个。虽然我们这里没有去做任何事情,它的配置文件也是默认为空,但是所有的属性都有一个默认值,比如端口号默认值为8080,上下文根默认为空。
我们如何去做一个对应的修改。就需要使用到我们的key:value来修改了。
我们在仅仅输入提示中可以看到,它默认的一个端口号就是8080.这个时候我们可以对其进行更改。更改的方式也是异常简单。
server.port=8081
如何去配置一个上下文根呢,可以通过以下指令来配置。
server.servlet.context-path=/springboot
什么是上下文根。在我们之前的启动页面,我们前端发一个index请求给服务器。直接在地址栏输入index即可。完整的地址栏也就是 localhost:8080/index 因为我们这里的默认的上下文根是 / , 所以直接可以通过index获取到对应的返回信息。但是在我们配置了上下文根后,就不能通过这样直接去访问的样式来去访问对应的请求了,需要在localhost:8080/对应的请求文根/请求地址 这样的方式来获取对应的请求信息。以图举例。
在我们的地址栏。可以直接在本地地址后加上请求的地址。即可获取到服务器返回的响应信息。但是在我们配置上下文根后,就需要在本地地址栏后面跟上对应的上下文根路径后面在加上请求的地址路径。如果不这样做,直接去访问请求路径。则会找不到地址。
我们应该加上对应的上下文根,这里我们配置的是上面的 /springboot。
YML格式的核心配置文件
yml文件,是一种yaml格式的配置文件,主要采用一定的空格,换行等格式排版进行配置。
yaml是一种直观的能够被计算机识别的数据序列化格式,容易被人阅读,yaml类似于xml,但是语法比xml简洁的很多。值与前面的冒号配置项必须要有一个空格,yml后缀也可以使用yaml。
这里有一个注意点。当yml和properties文件同时存在时,优先级properties文件优先级较高。会先执行properties文件,yml文件丢弃。所以这里我们为了方便,可以先更改properties文件的前缀名。使用yml配置。
在我们的项目中的resources文件夹下创建 application.yml。
这里还会有一种情况,创建yml文件时候,没有Spring托管的小绿叶标志。我们需要按照以下方法去做。
在File 目录下打开我们的项目工程。Ctrl + alt + shift + s 然后,在工程里的Modules 选中我们的项目文件,里面有一个Spirng。点击它,在右侧,有一个小绿叶的标志打开,然后点击 + 号。 把我们项目里的 yml/yaml文件添加即可。
呢么同样的,我们如何在Yml文件中配置端口和上下文根呢。也是很简单的。但是需要遵守一些约定。
server:
port: 8081
servlet:
context-path: /springboot
这样我们就可以配置完成。
我们为什么会这样写,我们先看看使用 properties。他们的级别分别是什么。
server.port=8081
server.servlet.context-path=/springboot
我们可以看到,他们的父级都是server,在第二级的时候,一个是port,一个是servler。他们有他们对应的子级,我们在properties中,必须把他们分开,全路径去写。但是在yml中,简化了这种写法。我们只需要按级去分,按级去写,两个为一缩进,在yml中,对空格有严格的要求,在每一个冒号和值的中间,都需要加上一个空格,这里需要注意。
SpringBoot工程多环境配置-功能实现
我们说过 application.properties 这个文件夹只允许有一个,并且是唯一的。
子环境核心配置文件的名称,是以: application-xxx.properties
主核心配置文件只能有一个,呢就是: application.properties
通过Value注解,获取自定义配置
如果我们的配置文件在主核心配置文件里,我们连解析都不需要去做,springboot已经帮我们去做了,如果是我们提前定义好的,他不是预留配置的,是自定义的。如何去读取。我们通过两种方式。
第一种,@Value注解
第二种,@ConfigurationProperties
现在,我们在properties文件里,配置以下属性。来充当我们的自定义数据
school.name=ApplicationContextAndClassPathApplicationContext
webs=baiDua.com
这一串数据你可以任意定义,你想怎么定义就怎么定义,你开心就好。
然后我们在Controller层里,进行书写我们的代码,新建一个类,HelloIndexController
然后我们 在类中这样去写。
package com.example.controller;
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("helloIndexController")
public class HelloIndexController {
@Value("${school.name}")
private String schoolName;
@Value("${webs}")
private String webs;
@RequestMapping("/index")
public @ResponseBody String index() {
return schoolName + " " + webs;
}
}
@Controller,标注了这个类,让他可以被SpringBoot扫描到,并且注册对象。然后我们的@Value进行去配置文件里取值,注意这是Spring的注解,而不是Lombok的注解。然后我们通过表达式来获取到值,${[值]}; 以这种形式,然后我们注入到对应的属性中。在下方去使用。
我们开启SpringBoot的运行。去查看结果是什么样子的,看看是否会显示 正确的结果。打开浏览器,输入对应的地址栏信息。我们可以看到如下结果,确实是获取到了自定义属性的值。
他只能写在控制层吗?不,你写在哪里都可以。@Service层,等其他层。全部可以正常获取到配置文件里的值。如果你放到数据持久层的话。。你总不能在sql语句里面去取吧。是吧。