1. 自定义starter介绍
自定义starter从下面两个方面着手:
- 这个自定义starter的场景需要用到哪些依赖?
- 如何编写自定义starter的自动配置?
查看springboot提供的已有starter组件的自动配置类,基本使用了下面的注解去实现一个自定义starter组件自动配置类。
@Configuration // 指定这是一个配置类
@ConditionalOnXXX // 在指定条件成立的情况下自动配置类才生效
@AutoConfigureOrder // 指定自动配置的加载顺序
@AutoConfigureAfter // 自动配置类在指定配置加载后才能加载
@Bean // 给容器中添加组件
@ConfigurationProperties // 结合XxxProperties类来绑定相关的配置属性
@EnableConfigurationProperties(XxxProperties.calss) // 让XxxProperties属性类生效并加入到容器中
自动配置类要实现应用启动就自动加载,需要将自定义的自动配置类配置到项目类路径下的META-INF/spring.factories
文件中。
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
启动器模块介绍
启动器模块是一个空Jar文件,仅提供辅助性依赖管理,依赖导入;这些依赖可能用于自动装配,自动装配一般专门写一个自动配置模块;启动器依赖自动配置模块,别人只需要引入启动器(starter)就能使用自动配置模块的功能。
启动器官方命名规范:spring-boot-starter-模块名
eg: spring-boot-starter-web, spring-boot-starter-actuator
自定义启动器命名规范:模块名-spring-boot-starter
eg: mybatis-spring-boot-starter, druid-spring-boot-starter
自动配置模块命名规范: 模块名-spring-boot-starter-autoconfigurer
2. 自定义starter实践
2.1 创建自动配置模块
创建自定义自动配置模块atguigu-spring-boot-starter-autoconfigurer
, 引入springboot自动配置的相关依赖。
<?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.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.atguigu.starter</groupId>
<artifactId>atguigu-spring-boot-starter-autoconfigurer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>atguigu-spring-boot-starter-autoconfigurer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
<dependencies>
<!--引入spring-boot-starter, 所有starter的基本配置-->
<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>
</dependencies>
</project>
创建HelloProperties类,用来绑定自动配置类需要用到的配置属性,使用者在全局配置文件application.yaml或properties文件中配置atguigu.hello.xxx就能进实现配置属性的绑定。
@ConfigurationProperties(prefix = "atguigu.hello")
public class HelloProperties {
private String prefiex;
private String suffix;
public HelloProperties() {
}
public HelloProperties(String prefiex, String suffix) {
this.prefiex = prefiex;
this.suffix = suffix;
}
public void setPrefiex(String prefiex) {
this.prefiex = prefiex;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public String getPrefiex() {
return prefiex;
}
public String getSuffix() {
return suffix;
}
}
编写自动配置类
@Configuration
@ConditionalOnWebApplication // Web应用才生效
@EnableConfigurationProperties(HelloProperties.class) // 绑定配置属性类并生效
public class HelloServiceAutoConfiguration {
@Autowired
private HelloProperties helloProperties;
// 自动配置类中实例化HelloServiceBean
@Bean
public HelloService helloService() {
HelloService helloService = new HelloService();
helloService.setHelloProperties(helloProperties);
System.out.println("create helloService bean finished");
return helloService;
}
// 编写自动配置的功能接口 HelloServiceBean
public class HelloService {
private HelloProperties helloProperties;
public void setHelloProperties(HelloProperties helloProperties) {
this.helloProperties = helloProperties;
}
public String sayHelloAtguigu(String name) {
return helloProperties.getPrefiex() + "-" + name + "-" +
helloProperties.getSuffix();
}
}
}
在项目类类路径下创建META-INF/spring.factories
文件,将自动配置类按照springboot自动配置的规范进行配置。
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.atguigu.starter.HelloServiceAutoConfiguration
2.2 创建启动器模块
创建自定义启动器atguigu-spring-boot-starter
, 启动器仅仅用来管理依赖,导入相关的依赖即可,不需要在里面写自动配置的代码, 在里面引入实现自动配置功能的自动配置模块。
<?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.atguigu.starter</groupId>
<artifactId>atguigu-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<!--启动器-->
<dependencies>
<!--引入自定义自动配置模块-->
<dependency>
<groupId>com.atguigu.starter</groupId>
<artifactId>atguigu-spring-boot-starter-autoconfigurer</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
2.3 使用自动配置功能
使用mvn install
将自动配置模块和自定义starter模块分别发布到maven仓库,方便其他人进行引入。
在springboot应用中导入自定义starter组件依赖。
<!--引入自定义starter-->
<dependency>
<groupId>com.atguigu.starter</groupId>
<artifactId>atguigu-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
在全局配置文件中配置自动配置类使用的配置属性
## 自定义starter的自动配置属性
atguigu.hello.prefiex=ATGUIGU
atguigu.hello.suffix=WORLD
编写测试代码
@RestController
public class HelloController {
@Autowired
private HelloService helloService;
@GetMapping("/starter/sayhello")
public String sayhello() {
return helloService.sayHelloAtguigu("haha");
}
}
测试结果: