第一章 学习SpringBoot的切入点
SpringBoot的作用: 简化所有Spring家族的框架整合
第二章 回顾(前置知识)
第三章 其他
第四章 Hello SpringBoot

SETP1: pom.xml配置
- 配置父类继承
<parent> - 添加SpringBoo-web工程的依赖
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| <?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.mts</groupId> <artifactId>Project_8_21</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> </parent> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project>
|
SETP2: XXXApplication启动类配置
- 命名: 启动类建议使用
项目名称+Application命名
1 2 3 4 5 6 7
| @SpringBootApplication public class Project821Application { public static void main(String[] args) { SpringApplication.run(Project821Application.class, args); } }
|
STEP3: 创建Cotroller进行页面响应
- 和一般的Controller没有什么区别
- 默认服务器为Tomcat; 端口号为8080
1 2 3 4 5 6 7
| @RestController public class HelloController { @RequestMapping("/hello") public String hello() { return "Hello SpringBoot!!!"; } }
|
第五章 关于配置文件
第一节 配置文件
- 位置: resources下
- 命名规则:
application-xxxx.后缀 - 后缀: ①properties ②yaml ③yml
- 底层: pom.xml依赖的父类中spring-boot-starter-parent

第二节 读取配置文件
5.2.1方式一: 使用@Value单个注入
1 2 3 4 5 6 7 8
| mts: spring: datasource: driverClassName: driverClassName url: url username: username password: password
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @Component public class DataSource { @Value("${mts.spring.datasource.driverClassName}") private String driverClassName;
@Value("${mts.spring.datasource.url}") private String url;
@Value("${mts.spring.datasource.username}") private String username;
@Value("${mts.spring.datasource.password}") private String password; }
|
1 2 3 4 5 6 7 8 9 10 11 12
| @RestController public class HelloController {
@Autowired private DataSource dataSource;
@RequestMapping("/datasource") public DataSource dataSource() { return dataSource; } }
|

5.2.2 方式二: 使用@ConfigurationProperties批量注入
1 2 3 4 5
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
|
1 2 3 4 5 6 7 8
| mts: spring: datasource: driverClassName: driverClassName url: url username: username password: password
|
1 2 3 4 5 6 7 8 9 10
| @Component @ConfigurationProperties(prefix = "mts.spring.datasource") public class DataSource { private String driverClassName; private String url; private String username; private String password; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| @RestController @EnableConfigurationProperties(DataSource.class) public class HelloController {
@Autowired private DataSource dataSource; @RequestMapping("/datasource") public DataSource dataSource() { return dataSource; } }
|
第三节 多环境profile切换配置
- 实现: 多个配置文件(**一个:**application.yaml用于指定, **多个:**application-xxx.yaml为多个环境)

1 2 3 4
| spring: profiles: active: dev
|
1 2 3 4
| com: mts: environment: dev
|
1 2 3 4
| com: mts: environment: pro
|
- 注意⚠️:
- ①如果
properties和yml文件都存在,不存在spring.profiles.active设置,如果有重叠属性,默认以properties优先 - ②如果设置了spring.profiles.active,并且有重叠属性,以active设置优先。(active只能设置一个)
- ③active指定不能写全称(e.g application-datasourc.yaml; 当要指定这个文件激活时, active: datasource; 否则环境找不到)
第四节 获取环境中的值 Environment
- 语法: Environment类是在SpringBoot初始化中注入的一个Bean, 可以直接@Autowired获取
- 常用方法:
String getProperty(String key); 可以通过这个检查是否正确读取配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13
| @SpringBootTest public class Test01 {
@Autowired private Environment environment;
@Test public void test01() { System.out.println(environment.getProperty("com.mts.environment")); } }
|
第六章 自动配置原理
第一节 源码解析SpringBoot如何完成SpringMVC的配置
参考资料—第二章
第二节 [案例]自定义启动类
- 需求: 定义一个连接池启动器 , 当用户引入了连接池启动依赖之后 , 项目中就已经自动配置了连接池(用户可以直接@Autowired DataSourc这个对象)
- 需要什么: ①一个实体类 读取配置文件 ②自动配置类 ③ spring.factories中引入
- 如何引入并使用: ①install自定义的启动类 ②pom.xml配置gav ③环境中添加必要的key ④即可使用DataSource

pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| <?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.mts</groupId> <artifactId>mts-jdbc-datasource</artifactId> <version>1.0-SNAPSHOT</version>
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.18</version> </parent>
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.12</version> </dependency> <dependency> <groupId>c3p0</groupId> <artifactId>c3p0</artifactId> <version>0.9.1.2</version> </dependency> </dependencies> </project>
|
DataSourceProperties 读取配置文件的实体类
1 2 3 4 5 6 7 8 9 10
| @Component @ConfigurationProperties(prefix = "mts.jdbc.datasource") public class DataSourceProperties { private String driverClassName; private String url; private String username; private String password; private String type; }
|
DataSourceAutoConfiguration 自动配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| @SpringBootConfiguration @EnableConfigurationProperties(DataSourceProperties.class) public class DataSourceAutoConfiguration {
@Autowired private DataSourceProperties dataSourceProperties;
@Bean @ConditionalOnProperty(value = "mts.jdbc.datasource.type", havingValue = "druid") public DataSource createDataSource() { DruidDataSource dataSource = new DruidDataSource(); dataSource.setDriverClassName(dataSourceProperties.getDriverClassName()); dataSource.setUrl(dataSourceProperties.getUrl()); dataSource.setUsername(dataSourceProperties.getUsername()); dataSource.setPassword(dataSourceProperties.getPassword()); return dataSource; }
@Bean @ConditionalOnProperty(value = "mts.jdbc.datasource.type", havingValue = "c3p0") public DataSource createDatasourceC3p0() throws PropertyVetoException { ComboPooledDataSource dataSource = new ComboPooledDataSource(); dataSource.setDriverClass(dataSourceProperties.getDriverClassName()); dataSource.setJdbcUrl(dataSourceProperties.getUrl()); dataSource.setUser(dataSourceProperties.getUsername()); dataSource.setPassword(dataSourceProperties.getPassword()); return dataSource; }
}
|
spring.factroies
1 2
| org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.mts.autoconfig.DataSourceAutoConfiguration
|
第七章 SpringBoot测试
pom.xml 添加依赖
1 2 3 4 5 6
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
|
测试类添加@SpringBootTest注解
org.springframework.boot.test.context.SpringBootTest;
测试方法添加@Test注解
org.junit.jupiter.api.Test
1 2 3 4 5 6 7 8 9 10 11
| @SpringBootTest public class Test01 {
@Autowired private Environment environment;
@Test public void test01() { System.out.println(environment.getProperty("com.mts.environment")); } }
|
第八章 SpringBoot整合Spring MVC
第一节 静态资源目录
和SpringMVC的区别: 因为SpringMVC是web项目, 有webapp这个包, 但这里的SpringBoot是jar包(虽然是web项 目)没有webapp这个包
如何解决: 在resource下创建一个static(4个都可以)目录即可, 在此目录下存放静态资源

第二节 整合Thymeleaf
pom.xml 导入thymeleaf的jar包
1 2 3 4 5
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency>
|
配置环境变量 (spring.thymeleaf.prefix)
1 2 3 4
| spring: thymeleaf: prefix: classpath:/static/ suffix: .html
|
第三节 拦截器
- 和SpringMVC的区别: SpringMVC是通过在springmvx.xml中添加
<mvc:interceptors>标签实现的, SpringBoot没 有这个配置文件, 所以具体的配置方法如下
8.3.1 STEP1: 编写一个拦截器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @Component public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("preHandle"); return true; }
@Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { System.out.println("postHandle"); }
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { System.out.println("afterCompletion"); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| @Configuration public class MvcConfiguration implements WebMvcConfigurer {
@Autowired private MyInterceptor myInterceptor;
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(myInterceptor).addPathPatterns("/hello"); } }
|
第四节 文件上传和下载
1 2 3 4 5 6
| @PostMapping("/uploadImage") public Result uploadImage(MultipartFile file) {
System.err.println(file); return Result.success(); }
|
1 2 3 4 5 6 7 8 9 10
| spring: servlet: multipart: enabled: true location: /path/to/store/files file-size-threshold: 0B max-file-size: 10MB max-request-size: 20MB resolve-lazily: false
|
第九章 SpringBoot整合Spring
第一节 整合JDBC Template

pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency>
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.22</version> </dependency>
|
application.yaml
1 2 3 4 5 6 7
| spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC username: root password: root
|
JdbcTemplate示例代码: 可以直接@Autowired使用JdbcTemplate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| @Repository public class UserDao { @Autowired private JdbcTemplate jdbcTemplate;
public int saveUser(User user) { String sql = "insert into user(username, password) values(?,?)"; int var0 = jdbcTemplate.update(sql, user.getUsername(), user.getPassword()); return var0; }
@Transactional public List<User> getUsers() { String sql = "select username, password from user"; RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class); List<User> res = jdbcTemplate.query(sql, rowMapper); return res; } }
|
第二节 整合AOP

pom.xml
1 2 3 4 5
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
|
AOP示例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @Component @Aspect public class UserLogging {
@Pointcut("execution(* com.mts.dao.UserDao.*(..) )") public void myPointcut() { }
@Around(value = "myPointcut()") public Object aroundMethod(ProceedingJoinPoint pjp) { String methodName = pjp.getSignature().getName(); Object[] args = pjp.getArgs(); Object res = null; try { System.out.println("[前置通知]:该方法的参数有: " + args); res = pjp.proceed(); System.out.println("[后置通知]:该方法的返回值内容有: " + res); } catch (Throwable throwable) { throwable.printStackTrace(); System.out.println("[异常通知]:异常为:" + throwable); } finally { System.out.println("[后置通知]"); } return res; } }
|
第三节 整合声明式事务

pom.xml
1 2 3 4
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
|
示例代码: 直接使用@Transaction注解即可
1 2 3 4 5 6 7 8 9
|
@Transactional(isolation = Isolation.SERIALIZABLE, timeout = 3,propagation = Propagation.REQUIRES_NEW) public List<User> getUsers() { String sql = "select username, password from user"; RowMapper<User> rowMapper = new BeanPropertyRowMapper<>(User.class); List<User> res = jdbcTemplate.query(sql, rowMapper); return res; }
|
第十章 SpringBoot整合 Mybtais

第一节 STEP1: pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency>
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency>
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.2</version> </dependency>
|
第二节 STEP2: application.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
spring: datasource: druid: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/test?serverTimezone=UTC username: root password: root
mybatis: type-aliases-package: com.mts.pojo
configuration: map-underscore-to-camel-case: true
mapper-locations: classpath:/mapper/*.xml
|
第三节 STEP3: 启动类加注解
1 2 3
| @SpringBootApplication @MapperScan("com.mts.dao") public class Project96Application {}
|
第十一章 跨域的实现
第一节 什么是跨域
11.1.1 跨域
- 因为①前后端分离 ②前后端是两个服务器 ③前端服务器和后端服务器的url不一样 ④前端服务器想向(使用ajax)发数据 ⑤形成跨域
- 前端服务器: VSCode “GoLive”开启的端口(5050)
- 后端服务器: java的话就是8080
- 这里就会有端口不一样, 用前端用ajax发的话就会有跨域

第二节 跨域如何实现
视频
11.2.1 对单个方法设置跨域
- 语法:
@CrossOrigin(origins="支持的跨域访问的url") - 位置: 放在方法的上面
1 2 3 4 5 6 7 8 9 10 11 12
|
@ResponseBody @RequestMapping("/data") @CrossOrigin(origins = "http://localhost:5500/") public Person getData(HttpServletResponse response) { Person person1 = new Person("双双", 18); return person1; }
|
11.2.2 对整个项目设置跨域
第十二章 自定义异常
第一节 如何实现自定义异常





统一异常处理与信息返回
STEP1: 创建统一信息返回类(Result)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| public class Resp<T> {
private int code = 200; private String msg = "success"; private T data;
private Resp(int code,String msg,T data){ this.code = code; this.msg = msg; this.data = data; }
public static <T> Resp success(T data){ Resp resp = new Resp(200, "success", data); return resp; }
public static <T> Resp success(String msg,T data){ Resp resp = new Resp(200,msg, data); return resp; }
public static <T> Resp error(AppExceptionCodeMsg appExceptionCodeMsg){ Resp resp = new Resp(appExceptionCodeMsg.getCode(), appExceptionCodeMsg.getMsg(), null); return resp; } public static <T> Resp error(int code,String msg){ Resp resp = new Resp(code,msg, null); return resp; }
public int getCode() { return code; }
public String getMsg() { return msg; }
public T getData() { return data; }
}
|
STEP2: 创建全局统一异常处理类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @ControllerAdvice public class GlobalExceptionHandler {
@ExceptionHandler(value = {Exception.class}) @ResponseBody public <T> Resp<T> exceptionHandler(Exception e){ if(e instanceof AppException){ AppException appException = (AppException)e; return Resp.error(appException.getCode(),appException.getMsg()); }
return Resp.error(500,"服务器端异常"); } }
|
STEP3: 自定义枚举类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public enum AppExceptionCodeMsg {
INVALID_CODE(10000,"验证码无效"), USERNAME_NOT_EXISTS(10001,"用户名不存在"), USER_CREDIT_NOT_ENOUTH(10002,"用户积分不足"); ;
private int code ; private String msg ;
public int getCode() { return code; }
public String getMsg() { return msg; }
AppExceptionCodeMsg(int code, String msg){ this.code = code; this.msg = msg; }
}
|
STEP4: 自定义异常类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| public class AppException extends RuntimeException{
private int code = 500; private String msg = "服务器异常";
public AppException(AppExceptionCodeMsg appExceptionCodeMsg){ super(); this.code = appExceptionCodeMsg.getCode(); this.msg = appExceptionCodeMsg.getMsg();
}
public AppException(int code,String msg){ super(); this.code = code; this.msg = msg;
}
public int getCode() { return code; }
public String getMsg() { return msg; }
}
|
STEP5 调用处
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| @RestController public class DemoController {
@GetMapping("demo") public Resp<String> demo1(String name){
if("ok".equals(name)){ return Resp.success("succ"); } if("err".equals(name)){ throw new AppException(AppExceptionCodeMsg.USERNAME_NOT_EXISTS); }
if("errcode".equals(name)){ throw new AppException(AppExceptionCodeMsg.INVALID_CODE); } if("0".equals(name)){ int i=1/0; }
if("notenough".equals(name)){ throw new AppException(AppExceptionCodeMsg.USER_CREDIT_NOT_ENOUTH); }
return Resp.success("default"); } @GetMapping("list") public Resp<List> list(){ List<String> list = Arrays.asList("zhangsan","lisi","wangwu");
return Resp.success(list); } }
|
第十三章 SpringBoot整合Log4j2
STEP1: 排除原生SpringBoot日志文件
- 否则会报这个错误

title1 2 3 4 5 6 7 8 9 10
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency>
|
STEP2: 添加依赖
title1 2 3 4 5
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
|
STEP3:添加log4j2.xml配置文件
- 位置: 直接放在resource下即可

title1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN"> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/> </Console> <File name="File" fileName="logs/app.log"> <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/> </File> <RollingFile name="RollingFile" fileName="logs/rolling.log" filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"> <PatternLayout> <pattern>%d %p %c{1.} [%t] %m%n</pattern> </PatternLayout> <Policies> <TimeBasedTriggeringPolicy /> <SizeBasedTriggeringPolicy size="10MB"/> </Policies> </RollingFile> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> <AppenderRef ref="File"/> <AppenderRef ref="RollingFile"/> </Root> </Loggers> </Configuration>
|