案例代码:https://gitee.com/flymini/codes01/tree/master/springboot_/starter_
****
**1. 为什么要自定义场景启动器**
* 可能官方提供的场景启动器不满足你的要求。
* 可能是你想开发一个被 SpringBoot 兼容的框架。比如 Mybatis 想要被 SpringBoot 兼容,则 Mybatis 团队自己开发了一个 mybatis 的场景启动器。
```xml
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
```
* 可能你想要在项目启动时自动加载一下依赖组件。
**2. 自定义场景启动器需考虑如下因素**
* 场景启动器需要引入哪些依赖。
* 自动配置类需要用到哪些注解。
[TOC]
# 1. WebMvcAutoConfiguration源码
1. 通过看 WebMvcAutoConfiguration 来了解一下编写一个场景启动器可能需要用到哪些注解。
```java
package org.springframework.boot.autoconfigure.web.servlet;
// 指定类为配置类
@Configuration(
proxyBeanMethods = false
)
// 当应用是Web应用时让该配置类生效
@ConditionalOnWebApplication(
type = Type.SERVLET
)
// 当存在Servlet、DispatcherServlet,WebMvcConfigurer时才让配置类生效
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
// 当不存在WebMvcConfigurationSupport才让这个配置类生效
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
// 指定该配置类生效的顺序,当大于0时,数字越小越先被执行
@AutoConfigureOrder(-2147483638)
// 指定在这三个类被执行后才能执行该配置类
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
@Bean // 将方法的返回值注入到IoC容器中,<bean class="方法返回值"/>,方法名作为<bean id="方法名"/>
@ConditionalOnMissingBean({HiddenHttpMethodFilter.class})
@ConditionalOnProperty(
prefix = "spring.mvc.hiddenmethod.filter",
name = {"enabled"},
matchIfMissing = false
)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
@Configuration(
proxyBeanMethods = false
)
@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
// 结合对应的XXXProperties来绑定相关的配置,这些配置就是在application.properties中可以配置的属性
// EnableConfigurationProperties让XXXProperties这些配置生效
@EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class})
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
...
}
```
2. 需要将该类配置在 META-INF/spring.factories 文件中才能使它生效。
![](https://img.kancloud.cn/87/75/8775fdd46a422f4f7c65fa332d3622d1_1305x298.jpg)
```xml
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
```
<br/>
# 2. 自定义场景启动器
## 2.1 创建自动配置类模块
**1. 创建模块:learn-custom-autoconfig**
```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 http://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.3.12.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.learn.example</groupId>
<artifactId>learn-custom-autoconfig</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
</dependencies>
</project>
```
**2. 当前模块的properties类**
```java
@Data
@ConfigurationProperties(prefix = "custom.config.account")
public class AccountProperties {
private String username;
private String password;
}
```
**3. 在当前模块提供一个获取properties类的API**
```java
@Data
public class AccountService {
private AccountProperties properties;
}
```
**4. 将AccountService注册到IoC容器中**
```java
@Configuration //标注该类为配置类
@ConditionalOnWebApplication //当前项目是Web应用时这个配置类生效
@EnableConfigurationProperties(AccountProperties.class) //将属性类加载到当前配置类中
public class CustomAutoConfiguration {
@Autowired
private AccountProperties properties;
@Bean
public AccountService getAccountService() {
AccountService impl = new AccountService();
impl.setProperties(properties);
return impl;
}
}
```
**5. 将配置类CustomAutoConfiguration添加到`resources/META-INF/spring.factories`**
```factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
learn.custom.autoconfig.config.CustomAutoConfiguration
```
>[info]提醒:不要给当前模块添加启动类。
<br/>
## 2.2 创建场景启动器模块
**1. 创建启动器模块:custom-spring-boot-starter**
![](https://img.kancloud.cn/a7/4f/a74fe2a5102fd1cb5ffe0869749b0134_1522x924.jpg)
![](https://img.kancloud.cn/6d/cb/6dcb120d6529abef1e385249f6cd88f3_1521x919.jpg)
```
/*********************启动器命名规范***************************/
------------ 官方命名空间 ------------
前缀:spring-boot-starter
模式:spring-boot-starter-模块名
举例:spring-boot-starter-web、spring-boot-starter-jdbc
------------ 自定义命名空间 ------------
后缀:spring-boot-starter
模式:模块名-spring-boot-starter
举例:mybatis-spring-boot-starter
```
**2. 在当前模块引入自动配置类模块**
```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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.learn.example</groupId>
<artifactId>custom-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.learn.example</groupId>
<artifactId>learn-custom-autoconfig</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
```
<br/>
## 2.3 创建项目来做测试
**1. 创建一个SpringBoot项目来做测试:com-custom-test**
```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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.learn.example</groupId>
<artifactId>com-custom-test</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<!-- 当前模块引入自定义场景启动器 -->
<dependency>
<groupId>com.learn.example</groupId>
<artifactId>custom-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
```
**2. 在当前模块的配置文件中给自动配置模块的properties赋值**
*`application.yml`*
```yml
custom:
config:
account:
username: zhangsan
password: 123456
```
**3. controller层调用自动配置类中的API**
```java
@RestController
public class IndexController {
@Autowired
private AccountService accountService;
@RequestMapping("/v1/auto/properties")
public AccountProperties getProperties() {
AccountProperties properties = accountService.getProperties();
System.out.println(properties);
//AccountProperties(username=zhangsan, password=123456)
return properties;
}
}
```
<br/>
通过上面的演示可以看出,com-custom-test 模块引入了场景启动模块,而场景启动器模块又引入了自动配置模块,所以可以在测试模块中可以调用到自动配置类的 API。
- Mybatis
- mybatis是什么
- mybatis优缺点
- 环境搭建
- 使用步骤
- 传参方式
- 无需传参
- 一个参数
- 多个参数
- 增/删/改
- 查询
- 单表查询
- 一对一查询
- 一对多查询
- 动态SQL
- 注解操作
- Spring
- Spring什么
- Spring优点
- Spring组成
- 第一个Spring程序
- 两大核心技术
- IoC控制反转
- IoC思想
- IoC容器使用步骤
- 属性注入
- IoC注入方式
- 模拟IoC实现
- AOP
- AOP概念
- AOP原理
- AOP关键术语
- AOP编程过程
- 切入点规则
- 5种增强方式
- Spring注解开发
- 注解开发的优势
- Bean注解开发
- AOP注解开发
- 完全注解开发
- 模拟Spring注解开发
- 自动装配
- 配置文件拆分
- SpringBean
- Bean常用属性
- Bean的作用域
- Bean的生命周期
- Spring整合MyBatis
- 整合步骤
- SqlSessionTemplate
- 业务层添加事务
- 事务的作用
- 配置文件事务
- 注解事务
- 事务参数
- SpringMVC
- SpringMVC是什么
- 环境搭建
- 请求流程
- 核心组件
- 前后端交互
- 简单交互演示
- 常用注解
- 后端数据传递至前端
- ServletAPI
- 访问静态资源
- 异常处理
- HandlerExceptionResolver
- 局部异常
- 全局异常
- 转发与重定向
- 转发演示
- 重定向演示
- 转发与重定向的区别
- 获取表单数据
- 表单标签
- REST风格的URL
- 异步处理
- 异步请求
- JSON数据处理
- 中文乱码处理
- 日期处理
- 上传文件
- 拦截器
- 视图解析器
- 视图类型
- 多视图解析器
- 自定义pdf视图
- JSR303数据验证
- JSR303是什么
- 常用约束
- 使用步骤
- SpringMVC整合Mybatis
- 整合步骤
- Mybatis分页插件
- SpringBoot
- SpringBoot是什么
- 环境搭建
- SpringBoot启动分析
- SpringBoot启动类
- 启动过程
- SpringBoot配置文件
- 配置文件类型
- 更改配置文件
- 读取配置文件
- 占位符
- 配置优先级
- 自定义IoC容器
- 定义方式
- 引入Spring配置文件
- @Configuration
- SpringBoot自动配置
- 自动配置原理
- 条件注解
- 自动配置报告
- 自定义自动配置
- 关闭自动配置
- 接管自动配置
- 多环境配置
- CommandLineRunner
- SpringBoot与Web开发
- 引入模板引擎
- Thymeleaf模板
- Freemarker模板
- 静态资源访问
- webjars
- 静态资源位置
- ico图标
- 指定首页
- 更换Web服务器
- 国际化
- 拦截器
- 错误处理机制
- 错误处理机制原理
- 定制错误页面
- 定制错误数据
- 上传文件
- 注册servlet三大组件
- 注册Servlet
- 注册过滤器
- 注册监听器
- 外部Tomcat与jsp模板
- 前后端交互
- 传递json字符串
- 传递js对象
- 传递表单
- 下载功能
- Swagger2文档
- SpringBoot整合JDBC
- 整合步骤
- 核心API
- JdbcTemplate
- 增删改
- 查询
- NamedParameterJdbcTemplate
- 增删改
- 查询
- SpringBoot整合Mybatis
- 整合步骤
- 切换为Druid数据源
- 添加事务
- Mybatis分页插件
- 场景启动器
- 场景启动器是什么
- 自定义场景启动器
- SpringBoot与日志
- 日志框架
- slf4j日志
- slf4j日志实现
- 统一切换为slf4j
- 日志配置
- 日志文件
- 切换日志框架
- 切换日志场景启动器
- SpringBoot与缓存
- JSR107缓存技术
- Spring缓存抽象
- 缓存注解
- SpEL表达式
- 使用缓存
- 自定义key生成器
- 缓存工作原理与流程
- SpringBoot整合Redis
- 整合步骤
- 初步使用
- 序列化机制
- 缓存管理器
- SpringBoot与任务
- 异步任务
- 实现异步任务
- 注意事项与原理
- 自定义线程池
- 定时任务
- cron表达式
- 创建定时任务
- @Scheduled参数
- 动态时间
- 邮件任务
- Quartz定时任务
- Quartz是什么
- 创建定时任务
- 触发器与任务
- 任务的CURD
- 两种触发器
- 并发问题
- 持久化
- 任务持久化
- Quartz集群
- misfire策略
- 打包插件
- appassembler-maven-plugin
- appassembler与assembly配合