SpringBoot 的 Starter 其实并没有什么神奇的。只是最近很多人问起我,而且我的百度搜索指数告诉我,最近搜索 druid-spring-boot-starter 的人在增多。于是,我今天便给大家科普一下,如何自定义实现一个 SpringBoot 的 Starter。
任何的学习都是先从模仿开始的,为此,我们先来看看 mybatis-spring-boot-starter 的结构。然后来对照着模仿一个。
首先,我们打开 mybatis-spring-boot-starter 的 pom.xml 文件,你会发现在它引用的众多 dependency 中有一个 mybatis-spring-boot-autoconfigure。其他的像 JDBC,Mybatis,Spring 都是非 starter 模式整合 Mybatis 必须的,可以忽略不看。
然后,我们顺着 mybatis-spring-boot-autoconfigure 去看看它的 pom.xml 文件。
你会发现里面有两个重要的引用 spring-boot-autoconfigure 和 spring-boot-configuration-processor。
为什么关注这两个呢?因为只有这两个才是 Spring Boot 提供的,其他的都不是。
如果你还没有发现规律,你可以在看看 spring-boot-starter-jdbc 的构造。看的 starter 多了后,你会发现,所有的 starter 中都引入了 spring-boot-configuration-processor 和 spring-boot-autoconfigure。
除此之外,我前面的文章还说过,@Conditional 注解在 SpringBoot 中启动承上启下的作用。根据 @Conditional 引出来的 @ConditionalOnClass、@ConditionalOnMissingBean、@ConditionalOnProperty 等共同构成了一些根据选择,按需配置。
在 SpringBoot 的脑图和源码解读中《看源码,我为什么建议你先从 SpringBoot 开始》,我也说过 @SpringBootApplication 会拿到各个 starter 中的 META-INF/spring.factories 中需要自动配置的类的全类名。把自动配置的类全名放入 ImportSelector 中,从而创建了自动配置类,根据自动配置类中的逻辑,进行相应的自动配置。
因此,根据上面的简单解读,下面我们就一起来动手撸一个自定义的 Starter。
先建一个 xttblog-spring-boot-starter 的 Maven 项目,pom.xml 中的配置如下:
<dependencies>
<!-- @ConfigurationProperties annotation processing (metadata for IDEs)
生成spring-configuration-metadata.json类,需要引入此类-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.13.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
其中 spring-boot-configuration-processor 的作用是编译时生成spring-configuration-metadata.json, 此文件主要给 IDE 使用,用于提示使用。如在intellij idea中,当配置此jar相关配置属性在application.yml, 你可以用 ctlr+ 鼠标左键,IDE 会跳转到你配置此属性的类中。没有 spring-boot-configuration-processor 不会出错,但是没有提示,不完美,所以,我们把它也加上。
另外,看我这个 Maven 项目的命名,xttblog-spring-boot-starter 符合 SpringBoot 的要求:{name}-spring-boot-starter。只有官方的 starter ,名字在后面。spring-boot-starter-{name},你可以看看上面我举例的 mybatis 和 druid,都符合命名规范。
接下来,我们的自定义 starter 实现一个简单业务。输入一个字符串,我们输出:“ say,hello字符串www.xttblog.com”。
public class XttblogHelloService {
private String prefix;
private String suffix;
public XttblogHelloService(String prefix, String suffix) {
this.prefix = prefix;
this.suffix = suffix;
}
public String sayHello(String word) {
return prefix + word + suffix;
}
}
然后定义 prefix 和 suffix 属性类。
@ConfigurationProperties("xttblog.hello.service")
public class XttblogHelloServiceProperties {
private String prefix;
private String suffix;
public String getPrefix() {
return prefix;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
}
接下来就是最重要的自动配置类。
@Configuration
@ConditionalOnClass(XttblogHelloService.class)
@EnableConfigurationProperties(XttblogHelloServiceProperties.class)
public class XttblogHelloAutoConfigure {
private final XttblogHelloServiceProperties properties;
@Autowired
public XttblogHelloAutoConfigure(XttblogHelloServiceProperties properties) {
this.properties = properties;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "xttblog.hello.service",
value = "enabled",havingValue = "true")
XttblogHelloService exampleService (){
return new XttblogHelloService(properties.getPrefix(),properties.getSuffix());
}
}
再重复一下,这几个关键的 @Conditional。
- @ConditionalOnClass,当 classpath 下发现该类的情况下进行自动配置。
- @ConditionalOnMissingBean,当 Spring Context 中不存在该 Bean 时。
- @ConditionalOnProperty 当配置文件中xttblog.hello.service=true时执行。
最后,别忘记了 spring.factories。在 resources/META-INF/ 下创建 spring.factories 文件,内容如下:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=/
com.xttblog.service.XttblogHelloAutoConfigure
最后,你可以运行 mvn:install 打包安装,一个自定义的 Spring Boot Starter 便开发完成了。然后你在其他 SpringBoot 项目中就可以这样使用 xttblog-spring-boot-starter。
<dependency>
<groupId>com.xttblog.demo</groupId>
<artifactId>xttblog-spring-boot-starter</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
具体的测试过程,我就不贴了。大家自己动手,收获更大!
以上,希望能够帮助到大家。需要 SpringBoot 源码解读和脑图的,请加我微信号:xmtxtt,备注:脑图,我免费发给你们。
: » 手把手教你打造一个SpringBoot自定义的Starter
原创文章,作者:dweifng,如若转载,请注明出处:https://blog.ytso.com/252074.html