这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」
思维导图
Spring Boot
Spring Boot是Spring公司的一个顶级项目,和Spring Framework是一个级别的。
Spring Boot实际上是利用Spring Framework 自动配置特性完成。编写项目时不需要编写xml文件。发展到现在,Spring Boot已经具有很很大的生态圈,各种主流技术已经都提供了Spring Boot的启动器。
启动器
启动器?Spring Boot框架在项目中作用是整合(整合的依赖)各种其他技术,让其他技术使用更加方便。
Spring Boot的启动器实际上就是一个依赖。这个依赖中包含了整个这个技术的相关jar包,还包含了这个技术的自动配置,以前绝大多数XML配置都不需要配置了。当然了,启动器中自动配置无法实现所有内容的自动配置,在使用Spring Boot时还需要进行少量的配置(这个配置不是在xml中了,而是在properties或yml中即可)。
如果是Spring自己封装的启动器的artifact id名字满足:spring-boot-starter-xxxx,如果是第三方公司提供的启动器满足:xxxx-spring-boot-starter。以后每次使用Spring Boot整合其他技术时首先需要考虑导入启动器。
作用
Spring Boot 利用Spring Framework 自动配置特性完成,多数xml不需要配置,整合其他技术,使用起来更加方便,组装完整环境的一个开发平台
Spring Boot特征
① 使用Spring Boot可以创建独立的Spring应用程序
② 在Spring Boot中直接嵌入了Tomcat、Jetty、Undertow等Web 容器,所以在使用SpringBoot做Web开发时不需要部署WAR文件
③ 通过提供自己的启动器(Starter)依赖,简化项目构建配置
④ 尽量的自动配置Spring和第三方库
⑤ 绝对没有代码生成,也不需要XML配置文件
Spring Boot核心
起步依赖:本质上是Maven项目对象模型,将具备某些功能的依赖坐标打包到一起,并提供一些默认功能
自动配置:自动完成Spring配置
Spring Boot版本介绍
SNAPSHOT:快照版,即开发版。
CURRENT:最新版,但是不一定是稳定版。
GA:General Availability,正式发布的版本
SpringBoot原理
SpringBoot是一个快速开发平台,底层是Spring Framework + YAML 解析实现。是通过AutoConfiguration实现自动配置,组装完整环境的一个开发平台。和任何技术没有冲突,只要可以和Spring Framework 整合的技术,都可以依托SpringBoot快速开发平台,提供基础环境
执行原理
通过注解@SpringBootApplication
,实现环境自动配置,
@SpringBootApplication注解中核心内容是:@SpringBootConfiguration、@EnableAutoConfiguration、@ComponenScan注解
@ComponenScan注解:扫描组件注解。默认扫描@SpringBootApplication注解描述类型所在,及所有子孙包。扫描组件实现容器初始化。如扫描到@Controller , 创建对应对象,标记为控制器,并维护在容器中。扫描到@Service,创建对象标记为服务对象,并在容器中维护
@SpringBootConfiguration:标注当前类是配置类,并会将当前类内声明的一个或多个以@Bean注解标记的方法的实例纳入到spring容器中,并且实例名就是方法名,允许在上下文中注册额外的 bean 或导入其他配置类
@EnableAutoConfiguration:开启自动配置,底层通过SpringFactoriesLoader类实现的读取spring.factories相关配置文件
在SpringBoot启动的时候,一定会初始化SpringFactoriesLoader对象,并自动扫描 classpath:/META-INF/spring.factories
(properties格式的配置文件)配置文件,读取其中的EnableAutoConfiguration对应的类型value,value
以逗号分隔的若干个配置类 ,加载到内存后,依次调用初始化环境,当xxxAutoConfiguration类型中的初始化逻辑执行结束后,SpringBoot环境准备完毕,后续逻辑更具自定义逻辑代码,对外提供服务
Spring Boot配置文件
有几种文件方式配置?
3种
-
application*.yml
-
application*.yaml
-
application*.properties
.properties文件配置方式
server.port=8888
spring.datasource.url=
spring.datasource.username=
spring.datasource.password=
.yml文件配置方式
注意
① 大小写敏感
② 使用缩进代表层级关系
③ 相同的部分只出现一次
④ 注意空格
.yaml文件配置方式于.yml相同
spring:
datasource:
driver-class-name:
url:
data-username:
data-password:
# 配置对象类型数据
student:
name:
sex:
age:
# json格式
person: {age: 12,sex: 男}
# 数组
arr:
- lis
- zs
- ww
arr2: [1,3,4,5]
配置文件存放位置
① 当前项目根目录中
② 当前项目根目录下的一个/config子目录中
③ 项目的resources即classpath根路径中
④ 项目的resources即classpath根路径下的/config目录中
.
│ application.yml
│ pom.xml
│ SpringBoot.iml
│
├─config
│ application.yml
│
└─src
├─main
│ ├─java
│ │ │ Application.java
│ │ │
│ │ └─com
│ │ └─test
│ │ ├─controller
│ │ ├─mapper
│ │ ├─pojo
│ │ └─service
│ ├─resources
│ │ │ application.yml
│ │ │
│ │ ├─config
│ │ │ application.yml
│ │ │
│ │ ├─public
│ │ ├─static
│ │ └─templates
│ └─webapp
└─test
配置文件存放执行顺序
/config—>当前项目根目录—>classpath/config—>classpath
.
│ application.yml ---------------------------------- 二
│ pom.xml
│ SpringBoot.iml
│
├─config
│ application.yml ---------------------------- 一
│
└─src
├─main
│ ├─java
│ │ │ Application.java
│ │ │
│ │ └─com
│ │ └─test
│ │ ├─controller
│ │ ├─mapper
│ │ ├─pojo
│ │ └─service
│ ├─resources
│ │ │ application.yml ------------------------ 四
│ │ │
│ │ ├─config
│ │ │ application.yml -------------------- 三
│ │ │
│ │ ├─public
│ │ ├─static
│ │ └─templates
│ └─webapp
└─test
配置文件格式加载顺序
**同目录下优先读取properties文件,在读取yml文件,优先使用properties文件中的内容**
bootstrap配置文件
Spring Boot 中有两种上下文对象,一种是 bootstrap, 另外一种是 application, bootstrap 是应用程序的父上下文,也就是说 bootstrap 加载优先于 applicaton。bootstrap 主要用于从额外的资源来加载配置信息,还可以在本地外部配置文件中解密属性。这两个上下文共用一个环境,它是任何Spring应用程序的外部属性的来源。bootstrap 里面的属性会优先加载,它们默认也不能被本地相同配置覆盖
bootstrap配置文件特征
- bootstrap(.xml或.properties) 文件命名
① boostrap 由父 ApplicationContext 加载,比 applicaton 优先加载。
② boostrap 里面的属性不能被覆盖。
bootstrap与 application 的应用场景
application 配置文件主要用于 Spring Boot 项目的自动化配置。
bootstrap 配置文件有以下几个应用场景:
① 使用 Spring Cloud Config 配置中心时,这时需要在 bootstrap 配置文件中添加连接到配置中心的配置属性来加载外部配置中心的配置信息。
② 一些固定的不能被覆盖的属性。
③ 一些加密/解密的场景。
FreeMarker 视图技术
FreeMarker是免费的,基于Apache许可证2.0版本发布
基于模板 + 要改变的数据,并用来输出文本(HTML网页、电子邮件、配置文件、源代码等)
Freemarker 模板语言是FTL文件编写的(Freemarker 文件后缀 .ftl)
参考文献: freemarker.apache.org/
FreeMarker优势
jsp技术是servlet 将jsp 编译成java 代码 然后通过java 代码处理响应给浏览器,这个过程响应比较慢
FreeMarker技术 将模板中占位变量 和 代码中响应给前台的数据 ,通过FreeMarker引擎 对接 直接输出响应给浏览器, 大大提高了响应速度
Spring Boot项目结构
│ pom.xml 依赖文件
│ SpringBoot.iml
│
└─src
├─main
│ ├─java
│ │ │ Application.java SpringBoot 启动类
│ │ │
│ │ └─com
│ │ └─test
│ │ ├─controller
│ │ ├─mapper
│ │ ├─pojo
│ │ └─service
│ ├─resources
│ │ │ application*.yml (或application*.properties) SpringBoot配置文件
│ │ │
│ │ ├─public 存放共享内容,对外公开
│ │ ├─static 存放静态资源
│ │ └─templates 存放thymeleaf页面或Freemarker(SpringBoot视图显示技术)
│ └─webapp 只有当页面使用jsp时才有
└─test
└─java
Spring Boot项目搭建
创建maven jar项目
配置pom.xml
新建控制器
新建启动类
启动项目
启动类
启动类和启动器的区别?
程序入口 启动类 :可以扫描当前包、子包下所有注解 启动类和启动器的区别: 启动类表示项目启动入口 启动器器表示jar包的坐标
启动类创建
package com.test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/*程序入口 启动类
* 可以扫描当前包、子包下所有注解
* 启动类和启动器的区别:
* 启动类表示项目启动入口
* 启动器器表示jar包的坐标
* */
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class,args);
}
}
Spring Boot 导入依赖
==SpringBoot 帮我整理好的依赖了一堆依赖,用的时候添加启动器依赖就行了==
==也有第三方公司提供的启动器==
方式一:继承父项目
<!--
方式1 继承spring-boot-starter-parent
推荐
-->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.13.RELEASE</version>
</parent>
方式二:不使用继承
<!--
方式2 依赖spring-boot-dependencies
不推荐 打包、连接池实现可能出现不兼容打包失败
-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.13.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
Spring Boot 异常处理+拦截器 +错误页面
异常处理
- 方式1: 在控制类控制单元方法添加 @ExceptionHandler 注解处理
- 方式2:编写类 使用注解@ControllerAdvice+@ExceptionHandler处理
- 方式3 :配置类实现HandlerExceptionResolver接口,编写异常处理方法
- 方式4: 配置类,Bean异常 SimpleMappingExceptionResolver方法处理
方式一
/**异常处理只在当前控制类有效*/
@ResponseBody
@ExceptionHandler(value = NullPointerException.class)
public String nullPointer(){
return "空指针异常";
}
方式二
全局有效
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(value = {java.lang.ArithmeticException.class})
public String test(Exception e){
System.out.println("1111111111111111");
return "error2";
}
}
方式三
全局有效
@Configuration
public class ExceptionController2 implements HandlerExceptionResolver{
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
ModelAndView modelAndView = new ModelAndView();
if (e instanceof NullPointerException){
System.out.println("空指针异常处理");
modelAndView.setViewName("error1");
}
return modelAndView;
}
}
方式四
全局有效
@Configuration
public class GlobalException2 {
@Bean
public SimpleMappingExceptionResolver simpleMappingExceptionResolver(){
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
Properties properties = new Properties();
/**
* 参数一:异常类型,并且是全名
* 参数二:视图名称
*/
properties.put("java.lang.NullPointerException","error3");
properties.put("java.lang.ArithmeticException","error4");
System.out.println("异常处理执行");
resolver.setExceptionMappings(properties);
return resolver;
}
}
拦截器
- 编写拦截器 实现HandlerInterceptor
- 配置拦截器 继承WebMvcConfigurer
编写拦截器
@Component
public class MyInterceptor implements HandlerInterceptor {
/*再进入控制单元方法之前执行*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("拦截器执行");
return false;
}
/*在进行数据处理和做出响应之间进行这个方法的调用*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/*在进行页面渲染的时候执行*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
配置拦截器
@Configuration
public class MyConfig implements WebMvcConfigurer {
@Autowired
private MyInterceptor myInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor).
addPathPatterns("/plannerList") /*拦截地址*/
.excludePathPatterns("/static/**"); /*排除拦截*/
}
}
@Component
public class LoginInterceptorConfig extends WebMvcConfigurationSupport {
@Autowired
private LoginInterceptor loginInterceptor;
/**
* 添加拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**");//拦截所有地址
super.addInterceptors(registry);
}
}
错误页面
设置具体的状态码页面
在templates/下新建error文件夹,在error中新建:状态.html的页面。例如当出现500时显示的页面为500.html
使用x进行模糊匹配
当出现5开头状态码的错误时,显示页面可以命名为5xx.html
当出现50开头状态码的错误时,显示页面可以命名为50x.html
统一显示错误页面
在templates下新建error.html。如果项目中不存在具体状态码的页面或没有使用x成功匹配的页面时,显示error.html作为错误显示页面。
Spring Boot 管理Bean
- 编写配置类
- 测试
配置类
@Configuration
public class MyConfig {
@Bean
public User getUser(){
User user = new User("lys","nan","123");
return user;
}
@Bean("getUser1")
public User getUser1(){
User user = new User("aaa","nan","123");
return user;
}
@Bean
public String temp(){
return new String("test Bean test");
}
}
测试
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {Application.class})
public class TestBean {
@Qualifier("getUser1") /*查找Bean对象*/
@Autowired
private User user;
@Autowired
private String temp;
@Test
public void test1(){
System.out.println(user);
}
@Test
public void test2(){
// System.out.println(getUser1);
}
@Test
public void test3(){
System.out.println(temp);
}
}
Spring Boot整合SpringMVC
<!--SpringMVC 启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Spring Boot整合MyBatis
<!--MyBatis 启动器-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.1</version>
</dependency>
<!--JDBC数据库连接-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
Spring Boot 整合Druid
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
Spring Boot 整合Pagehelper
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.13</version>
</dependency>
Spring Boot整合FreeMarker
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
Spring Boot 整合thymeleaf
<!--thymeleaf启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
Spring Boot 整合JSP
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
Spring Boot整合logback
Spring Boot 默认使用Logback组件作为日志管理
Logback是由log4j创始人设计的一个开源日志组件
只需要在文件项目中resource加入logback.xml文件 配置日志
logback.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径-->
<property name="LOG_HOME" value="${catalina.base}/logs/" />
<!-- 控制台输出 -->
<appender name="Stdout" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志输出编码 -->
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名-->
<FileNamePattern>${LOG_HOME}/server.%d{yyyy-MM-dd}.log</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
</pattern>
</layout>
<!--日志文件最大的大小-->
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<!-- 日志输出级别 -->
<root level="info">
<appender-ref ref="Stdout" />
<appender-ref ref="RollingFile" />
</root>
<logger name="com.any.mapper" level="DEBUG"></logger>
<!--日志异步到数据库 -->
<!-- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
日志异步到数据库
<connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
连接池
<dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
<driverClass>com.mysql.jdbc.Driver</driverClass>
<url>jdbc:mysql://127.0.0.1:3306/databaseName</url>
<user>root</user>
<password>root</password>
</dataSource>
</connectionSource>
</appender> -->
</configuration>
Spring Boot整合Juint
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
测试类需要添加注解
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {启动类.class})
Spring Boot整合Quartz
<!--SpringBoot结合quartz的启动器-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-quartz</artifactId>
</dependency>
Spring Boot开发工具
避免每次修改java代码,重复启动形目
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
Spring Boot 打包插件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
Spring Boot部署
打jar包
-
1.修改项目为jar类型
-
2.添加Spring Boot 打包插件
-
3.安装jar包
-
4.将打好的包运行
1.修改项目为jar类型
<packaging>jar</packaging>
2.添加Spring Boot 打包插件
3.安装jar包
4.将打好的包运行
java -jar 包名
打war包
- 1.将项目修改为war类型
- 2.SpringMVC启动器排除Tomcat
- 3.添加tomcat启动器,只在运行阶段有效
- 4.添加打包插件
- 5.安装
- 6.部署到TomCat 服务器
1.将项目修改为war类型
<packaging>war</packaging>
2.SpringMVC启动器排除Tomcat
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
3.添加tomcat启动器,只在运行阶段有效
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
4.添加打包插件
5.安装
6.部署到TomCat 服务器(这里就不做演示了)