目录
一、介绍
为什么自定义spring-boot-starter组件?我们以该问题作为切入点进行分析。当然,每个人有自己不同的理解,这里仅结合我所接触的业务进行分享:
1、使用自定义starter组件之前:
在我们还没有使用自定义stater组件之前,通常,我们会将一些通用的功能封装在一个项目模块之中(避免每个项目写重复代码,可封装如数据源切换、安全校验之类的代码),再打包成jar包,发布到maven私仓中,供其他项目引入使用。
其他项目在引用时,由于我们封装的jar包中通常都使用了Spring相关的注解,导致引入jar包之后,还需要再启动类上加上@ComponetScan注解,进行jar包下的注解扫描。
一般情况下,我们自己封装的jar包都不少,除非我们每一个jar包的groupId都有一个统一的基础路径,否则的话,当我们每引入一个jar包时,都要添加一个包扫描路径,越到后期,就越难维护。
2、使用自定义starter组件之后:
基于使用自定义starter组件之前的jar包使用模式,我们就在想,是否有一种方式,我们在引入jar时,不再需要自己手动添加包扫描路径了,而是Spring Boot他自己就知道去哪里扫描。
答案是有的,那就是使用Spring Boot提供的自动装配,使用也不难,我们遵从Spring Boot的要求进行jar包开发,在项目启动时,就会扫描我们的相关配置,进行Bean创建。
接下来会附上详细的Starter开发流程,请大家耐心看完。
结合下篇文章效果更佳(个人建议可以先体验Starter开发,再看原理):
[Spring Boot Starter系列]Spring Boot自动装配原理_明天再去学习的博客-CSDN博客
二、starter组件命名规则
官方:
spring-boot-stater-模块
如,spring-boot-stater-web
自定义:
模块-spring-boot-stater
如,mybatis-spring-boot-stater
三、my-spring-boot-starter组件开发
1、创建项目,此处略
2、pom文件如下
<?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>org.ricardo.learn</groupId>
<artifactId>my-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<!-- Compile dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</build>
</project>
3、创建MyProperties类,用于读取配置文件下的配置
@ConfigurationProperties(prefix = "my")
public class MyProperties {
private String name = "my-spring-boot-starter";
private String type = "default";
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
引入该组件之后,就会读取到配置文件中my.name和my.type两个配置,由于我们设置了默认值,如果在配置文件中没有配置以上两个属性,那么就会使用默认值。
-
@ConfigurationProperties(prefix = "my"),用于将配置文件中前缀为my的相关配置映射到MyPropertis bean对象中。这样,通过注入MyPropertis,就能够获取到配置文件中的配置。
4、创建MyAutoConfiguration类,用于创建Bean
@Configuration
@ConditionalOnClass(MyProperties.class)
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {
private Logger logger = LoggerFactory.getLogger(MyAutoConfiguration.class);
@Bean("helloBean")
@ConditionalOnMissingBean(name = "helloBean")
public String helloBean(MyProperties myProperties){
logger.info("进入创建");
return myProperties.getName() + "-" + myProperties.getType();
}
}
该类是Starter组件的扫描的主入口(个人理解),当引入该Starter组件的项目进行启动时,通过配置扫描到该类,进行Bean的创建。因为之前我们说过,在启动类上添加@ComponetScan很麻烦,难以维护,那么我们可以将该注解添加到这个类上,当项目启动时,扫描到这个类时,就能知道我们需要扫描这个Starter组件的哪些包路径了。
-
@ConditionalOnClass(MyProperties.class),当指定的类存在时,才会实例化一个类
-
@EnableConfigurationProperties(MyProperties.class),启用属性配置,将读取MyProperties里面的属性(我的理解时实例化一个MyProperties的Bean)
-
@ConditionalOnMissingBean(name = "helloBean"),如果容器中没有该bean,就会创建一个bean
5、resource目录下创建META-INF文件夹,在其中创建spring.factories文件,内容如下
org.springframework.boot.autoconfigure.EnableAutoConfiguration=org.ricardo.learn.MyAutoConfiguration
可以说,这个文件才是Starter组件的总入口,也就是梦开始的地方,扫描到MyAutoConfiguration类后,就会获取到该类上标注的相关注解(在该类上标注@CompoentScan的原因就是这个),如果符合条件的话会进行注册。
四、使用
1、使用mvn clean install命令将Starter组件打成jar包,并且发送到我们本地maven仓库
2、其他项目引入该jar包依赖
<dependency>
<groupId>org.ricardo.learn</groupId>
<artifactId>my-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
3、启动项目,即可使用该Starter组件功能了