1、Spring Boot 简介
1. Spring Boot 介绍
SpringBoot
是由 Pivotal
团队提供的全新框架,其设计目的是用来==简化== Spring
应用的==初始搭建==以及==开发过程==。
使用了 Spring
框架后已经简化了我们的开发。而 SpringBoot
又是对 Spring
开发进行简化的,可想而知 SpringBoot
使用的简单及
广泛性。既然 SpringBoot
是用来简化 Spring
开发的。SpringBoot
框架解决了传统的Spring项目在配置和部署上的复杂性,简化开发流程,提升开发效率;
-
开发传统的 Spring 项目时,增加一个框架,就需要增加一组Bean配置,并且需要配置Bean之间依赖关系;随着项目的开发,项 目越来越大,配置文件或Bean对象的配置越来越多,Spring Bean 配置管理也就越来越复杂了。
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"
....
bean>
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
两个对象之间的依赖关系 依赖注入
<property name="dataSource" ref="dataSource"
bean>
-
部署阶段,对于 Web MVC 项目来说,需要自己配置Tomcat服务器,然后需要将项目打成war包,发布到外部Servlet容器中(Tomcat的webapps目录下),部署方式 也比较复杂。
2. Spring Boot 特点
-
可以创建独立的Spring应用程序
-
内置了Tomcat、Jetty、Undertow等web服务器,不需要部署war包
-
提供了starter依赖简化构建配置
-
尽可能自动配置Spring和第三方框架
-
提供了生产就绪的功能:监控、健康检查、外部化配置等
-
没有代码生成,也不需要XML配置
3. 创建Spring Boot 项目的方式
-
在 https://start.spring.io网站上创建
-
使用IDEA的Spring Initializr工具创建
-
手动创建
-
创建项目,配置 Maven 依赖
<!-- 管理 Maven 依赖 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
</parent>
<!--
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>3.2.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
-->
<dependencies>
<!-- spring-boot-starter-web -->
<!-- 自动配置了Tomcat、Spring MVC、Jackson、Logback等 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
-
编写启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
/**
* @ComponentScan: 默认从当前类所在的包开始扫描
* @EnableAutoConfiguration: 启动自动配置
*/
@ComponentScan
@EnableAutoConfiguration
//@SpringBootApplication //可以替代以上两个注解
public class HelloApplication {
public static void main(String[] args) {
/*
* 第一个参数: 当前类的 Class对象
* 第二个参数: 主方法参数 - 可选参数
*/
SpringApplication.run(HelloApplication.class, args);
}
}
-
编写controller
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(String name) {
return "Hello " + name;
}
}
-
启动项目
-
发送请求
4. 分析
-
@SpringBootApplication 注解是 Spring Boot 项目的核心注解,主要作用是开启Spring 自动配置,如果在 Application 类上去掉该注解,那么不会启动 SpringBoot程序
-
main 方法是一个标准的 Java 程序的 main 方法,是boot项目启动运行的入口
-
@RestController及 @RequestMapping 依然是我们之前的 Spring MVC,因为 Spring Boot 的里面依然是使用我们的 Spring MVC + Spring + MyBatis 等框架
5. 父工程
-
从pom文件中可以看到指定了一个父工程,我们进入到父工程,发现父工程中又指定了一个父工程。
-
再进入到该父工程中,在该工程中我们可以看到配置内容结构如下图所示
-
上图中的
properties
标签中定义了各个技术软件依赖的版本,避免了我们在使用不同软件技术时考虑版本的兼容问题。
-
dependencyManagement
标签是进行依赖版本锁定,但是并没有导入对应的依赖;如果我们工程需要那个依赖只需要引入依赖的groupid
和artifactId
不需要定义version
。
-
而
build
标签中也对插件的版本进行了锁定。
2、配置文件
2.1 配置文件格式
SpringBoot
提供了多种属性配置方式
-
application.properties
#设置内嵌 Tomcat 端口号 server.port=8888 #配置项目上下文根 server.servlet.context-path=/boot
-
application.yml
server: port: 81
-
yml 是一种 yaml 格式的配置文件,主要采用一定的空格、换行等格式排版进行配置。它能够直观的被计算机识别数据序列化格式,容易被人类阅读,yaml 类似于 xml,但是语法比 xml 简洁很多,值与前面的冒号配置项必须要有一个空格, yml 后缀也可以使用 yaml 后缀 。
-
-
application.yaml
server: port: 82
==注意:
SpringBoot
程序的配置文件名必须是application
,只是后缀名不同而已。==
2.2 多环境配置
在实际开发的过程中,我们的项目会经历很多的阶段(开发->测试->上线),每个阶段的配置也会不同,例如:端口、上下文根、数据库等,那么这个时为了方便在不同的环境之间切换,SpringBoot 提供了多环境配置。
-
application-dev.yml
#设置开发环境配置 server: port: 8080 #设置 Tomcat 内嵌端口号 servlet: context-path: /dev #设置上下文根
-
application-product.yml
#设置生产环境配置 server: port: 80 servlet: context-path: /product
-
application-test.yml
#设置测试环境配置 server: port: 9090 servlet: context-path: /test
-
在application.yml激活环境
#springboot 总配置文件 #激活开发环境 #spring: # profiles: # active: dev #激活测试环境 #spring: # profiles: # active: test #激活生产环境 spring: profiles: active: product
3、Spring Boot 切换 Servlet 服务器
-
默认情况下 Spring Boot 启动的是 Tomcat
-
修改依赖
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <!-- 排除Tomcat Starter --> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <!-- 导入Jetty Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency> </dependencies>
-
修改成功
4、Spring Boot 整合 MyBatis
-
导入依赖
Spring Boot 集成 MyBatis,需要导入 mybatis-spring-boot-starter 和 mysql 的依赖。 MyBatis-Spring-Boot-Starter 可以帮助你更快地在 Spring Boot 之上构建 MyBatis 应用。
MyBatis-Spring-Boot-Starter版本要求
<!--MyBatis 整合 SpringBoot 的起步依赖-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!--MySQL 的驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
-
修改 application.yml 文件
server:
#配置内嵌 Tomcat 端口号
port: 8080
spring:
datasource: # 数据库配置
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/et2402?serverTimezone=Asia/Shanghai
username: root
password: root
mybatis:
# 指定别名
type-aliases-package: com.exec
#指定Mybatis的Mapper文件
mapper-locations: classpath:mapper/**/*.xml
configuration:
#指定mybatis输出日志的位置, 输出控制台
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
-
开发代码
(1)在controller包下创建 StudentController 并编写代码
/**
* @RestController = @Controller + @ResponseBody
*/
@RestController
@RequestMapping("/student")
public class StudentController {
@Autowired
StudentService studentService;
@GetMapping("/getStudent")
public Student getStudent(int id) {
return studentService.getStudent(id);
}
}
(2)在在 service 包下创建 StudetnService 接口并编写代码
public interface StudentService {
Student getStudent(int id);
}
(3)在 service.impl 包下创建 StudentService的实现类并编写代码
@Service
public class StudentServiceImpl implements StudentService {
@Autowired
StudentMapper studentMapper;
@Override
public Student getStudent(int id) {
return studentMapper.getById(id);
}
}
(4)在mapper包下创建StudentMapper并编写代码
public interface StudentMapper {
/**
* 查询学生详情
*/
Student getById(int id);
}
(5) 在 resources 目录下新建目录 mapper 存放映射文件,并在mapper目录下创建 StudentMapper.xml 并编写代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.exec.mapper.StudentMapper">
<select id="getById" parameterType="int" resultType="student">
select id,
name,
age,
email,
schid,
birth,
visit
from student
where id = #{value}
</select>
</mapper>
(6) 启动项目,并发起请求
5、Spring Boot 开启事务
Spring Boot事务底层依然采用的是 Spring 本身提供的事务管理。Spring Boot 会自动注入 DataSourceTransactionManager,我们不需要任何其他的配置就可以用 @Transactional
注解进行事务的使用。
-
在启动类中使用注解@EnableTransactionManagement开启事务支持
-
在访问数据库的service方法上添加注解@Transactional即可
"资源"是一种信息实体,它可以有多种外在表现形式。我们把"资源"具体呈现出来的形式,叫做它的"表现 层"(Representation)。 比如,文本可以用txt格式表现,也可以用HTML格式、XML格式、JSON格式表现,甚至可以采用二进制格式;图 片可以用JPG格式表现,也可以用PNG格式表现。 URI只代表资源的实体,不代表它的形式。严格地说,有些网址最后的".html"后缀名是不必要的,因为这个后缀 名表示格式,属于"表现层"范畴,而URI应该只代表"资源"的位置。它的具体表现形式,应该在HTTP请求的头信息 中用Accept和响应头的Content-Type字段指定,这两个字段才是对"表现层"的描述。
6、Spring Boot 实现RESTFUL
1. 简介
REST全称Representational State Transfer意为表现层状态转移,表示资源在网络中以某种表现形式进行状态转移。它是一种互联网软件设计的风格,它只是提出了一组客户端和服务器交互时的架构理念和设计原则,基于这种理念和原则设计的接口可以更简洁,更有层次。
-
客户端用到的手段,目前是HTTP协议。具体来说,就是HTTP协议里面,四个表示操作方式的动词:GET、 POST、PUT、DELETE。它们分别对应四种基本操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源。
2. 主要注解
-
@PathVariable :获取 url 中的数据,该注解是实现 RESTFul 最主要的一个注解
-
@PostMapping :接收和处理post方式的请求
-
@DeleteMapping:接收delete方式的请求,可以用GetMapping代替
-
@PutMapping :接收put方式的请求,可以用 PostMapping 代替
-
@GetMapping :接收get方式请求
3. 传统方式和Rest风格对比
7、Spring Boot 配置跨域过滤器
1. 什么是跨域
跨域:浏览器对于javascript的同源策略的限制 。(没有浏览器参与的请求,不需要考虑跨域)
同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据。
同源是指两个请求的协议、主机、端口号一致,而主要其中有一个不一致就会发生跨域问题。
下表给出了与 URL http: store.company.com/dir/page.html
的源进行对比的示例:
协议:http
主机: store.company.com
端口号:80
2. 跨源资源共享(CORS)
ORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。是一种规范化的跨域请求解决方案,安全可靠。它可以在在服务端进行控制是否允许跨域,可自定义规则,支持各种请求方式,但是会产生额外的请求(预检)。
-
实现原理
-
跨域请求会在正式发送请求之前发送预检请求,询问服务器是否允许跨域访问;
-
服务器收到预检请求后,如果服务器否定了"预检"请求,会返回一个正常的HTTP回应,但是没有任何CORS相关的头信息字段。这时,浏览器就会认定,服务器不同意预检请求,就会直接报错;
-
服务器收到"预检"请求以后,检查了Origin、Access-Control-Request-Method和Access-Control-Request-Headers字段以后,确认允许跨源请求,就可以做出回应。
-
然后浏览器发送真实请求,
-
服务器返回结果。
-
3. 自定义过滤器实现跨域
-
创建跨域过滤器
public class CrossDomainFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletResponse resp = (HttpServletResponse)response;
//匹配某个域 协议:主机:port | http: localhost:3000 * 表示任意域都可访问
resp.setHeader("Access-Control-Allow-Origin", "*");
resp.setHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE,OPTIONS");
resp.setHeader("Access-Control-Allow-Headers", "*");
// OPTIONS 有效时长 前提两次请求相同
// 如果在有效时长内 之后的OPTIONS 预检请求不会发送 直接走 第三步和第四步
resp.setHeader("Access-Control-Max-Age", "3600");
//放行
chain.doFilter(request, resp);
}
}
-
配置跨域过滤器
@Configuration
public class MVCConfig implements WebMvcConfigurer {
/** 跨域处理 */
@Bean
public FilterRegistrationBean<CrossDomainFilter> crossDomainFilterBean() {
FilterRegistrationBean<CrossDomainFilter> registration = new FilterRegistrationBean();
registration.setFilter(new CrossDomainFilter());
registration.addUrlPatterns("/*");
// 值越小越先执行
registration.setOrder(-100);
return registration;
}
}
8、Spring Boot 静态资源处理
-
Spring Boot 默认处理方式
-
自定义
(1)application.yml
方式
mvc:
static-path-pattern: /files/**
web:
resources:
static-locations: file:D:/yitu/upload
(2)静态资源配置类
@Configuration
public class MVCConfig implements WebMvcConfigurer {
//静态资源处理
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//registry.addResourceHandler("/upload/**")
// .addResourceLocations("classpath:/upload/");
registry.addResourceHandler("/files/**")
.addResourceLocations("file:d/upload/");
}
}
9、全局异常处理器
-
-
定义全局异常处理器非常简单,就是定义一个类,在类上加上一个注解@RestControllerAdvice,加上这个注解就代表我们定义了一个全局异常处理器。
-
在全局异常处理器当中,需要定义一个方法来捕获异常,在这个方法上需要加上注解@ExceptionHandler。通过@ExceptionHandler注解当中的value属性来指定我们要捕获的是哪一类型的异常。
-
@RestControllerAdvice
public class GlobalExceptionHandler {
//处理异常
@ExceptionHandler(Exception.class) //指定能够处理的异常类型
public Result ex(Exception e){
e.printStackTrace();//打印堆栈中的异常信息
//捕获到异常之后,响应一个标准的Result
return Result.error("对不起,操作失败,请联系管理员");
}
}
@RestControllerAdvice = @ControllerAdvice + @ResponseBody
处理异常的方法返回值会转换为json后再响应给前端
以上就是全局异常处理器的使用,主要涉及到两个注解:
-
@RestControllerAdvice //表示当前类为全局异常处理器
-
@ExceptionHandler //指定可以捕获哪种类型的异常进行处理