前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >编写自己的SpringBoot-starter

编写自己的SpringBoot-starter

作者头像
java思维导图
发布2019-07-19 14:48:40
6760
发布2019-07-19 14:48:40
举报
文章被收录于专栏:java思维导图java思维导图
  • 作者:Vincent.Y
  • https://www.cnblogs.com/yuansc/p/9088212.html
  • 由公众号java思维导图排版

前言

我们都知道可以使用 SpringBoot 快速的开发基于 Spring 框架的项目。由于围绕 SpringBoot 存在很多开箱即用的 Starter 依赖,使得我们在开发业务代码时能够非常方便的、不需要过多关注框架的配置,而只需要关注业务即可。

例如我想要在 SpringBoot 项目中集成 Redis,那么我只需要加入 spring-data-redis-starter 的依赖,并简单配置一下连接信息以及 Jedis 连接池配置就可以。这为我们省去了之前很多的配置操作。甚至有些功能的开启只需要在启动类或配置类上增加一个注解即可完成。

那么如果我们想要自己实现自己的 Starter 需要做些什么呢?下面就开始介绍如何实现自己的 SpringBoot-xxx-starter。

原理

首先说说原理,我们知道使用一个公用的 starter 的时候,只需要将相应的依赖添加的 Maven 的配置文件当中即可,免去了自己需要引用很多依赖类,并且 SpringBoot 会自动进行类的自动配置。那么 SpringBoot 是如何知道要实例化哪些类,并进行自动配置的呢? 下面简单说一下。

首先,SpringBoot 在启动时会去依赖的 starter 包中寻找 resources/META-INF/spring.factories 文件,然后根据文件中配置的 Jar 包去扫描项目所依赖的 Jar 包,这类似于 Java 的 SPI 机制。

第二步,根据 spring.factories配置加载AutoConfigure类。

最后,根据 @Conditional注解的条件,进行自动配置并将 Bean 注入 Spring Context 上下文当中。

我们也可以使用

@ImportAutoConfiguration({MyServiceAutoConfiguration.class}) 指定自动配置哪些类。

实现

终于到了代码实现的步骤,接下来就开始编码我们自己的 SpringBoot-starter。

第一步创建一个 SpringBoot 项目,并添加下面两个依赖到 pom.xml 文件当中
<dependencies>
    <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>

其中 spring-boot-configuration-processor 的作用是编译时生成 spring-configuration-metadata.json ,此文件主要给 IDE 使用。如当配置此 jar 相关配置属性在 application.yml ,你可以用 ctlr + 鼠标左键点击属性名,IDE 会跳转到你配置此属性的类中。

我们日常使用的 Spring 官方的 Starter 一般采取spring-boot-starter-{name} 的命名方式,如 spring-boot-starter-web 。

而非官方的 Starter,官方建议 artifactId 命名应遵循{name}-spring-boot-starter 的格式。 例如:ysc-spring-boot-starter 。

<groupId>com.ysc</groupId>
  <artifactId>simple-spring-boot-starter</artifactId>
  <version>1.0.0-SNAPSHOT</version>
<packaging>jar</packaging>
第二步编写我们的 Service 类

这里讲一下我们的 Starter 要实现的功能,很简单,提供一个Service,包含一个能够将配置文件中配置的字符串根据传入的字符进行分割的方法String[] split(String separatorChar)。

public class StarterService {
    private String config;

    public StarterService(String config) {
        this.config = config;
    }
    
    public String[] split(String separatorChar) {
        return StringUtils.split(this.config, separatorChar);
    }
}
第三步编写配置文件读取类
@ConfigurationProperties("example.service")
public class StarterServiceProperties {
    private String config;
    
    public void setConfig(String config) {
        this.config = config;
    }
    
    public String getConfig() {
        return config;
    }
 }
第四步,编写AutoConfigure类 ,这步是关键点
@Configuration
@ConditionalOnClass(StarterService.class)
@EnableConfigurationProperties(StarterServiceProperties.class)
public class StarterAutoConfigure {

    @Autowired
    private StarterServiceProperties properties;

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "example.service", value = "enabled", havingValue = "true")
    StarterService starterService (){
        return new StarterService(properties.getConfig());
    }
}

解释一下代码中用到的几个注解:

  • @ConditionalOnClass,当classpath下发现该类的情况下进行自动配置。
  • @ConditionalOnMissingBean,当Spring Context中不存在该Bean时。
  • @ConditionalOnProperty(prefix = "example.service",value = "enabled",havingValue = "true"),当配置文件中example.service.enabled=true时。
下面列举 SpringBoot 中的所有 @Conditional 注解及作用
@ConditionalOnBean:当容器中有指定的Bean的条件下  
@ConditionalOnClass:当类路径下有指定的类的条件下  
@ConditionalOnExpression:基于SpEL表达式作为判断条件  
@ConditionalOnJava:基于JVM版本作为判断条件  
@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置  
@ConditionalOnMissingBean:当容器中没有指定Bean的情况下  
@ConditionalOnMissingClass:当类路径下没有指定的类的条件下  
@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下  
@ConditionalOnProperty:指定的属性是否有指定的值  
@ConditionalOnResource:类路径下是否有指定的资源  
@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者在有多个Bean的情况下,用来指定首选的Bean 
@ConditionalOnWebApplication:当前项目是Web项目的条件下  
最后一步,在resources/META-INF/下创建spring.factories文件,并添加如下内容:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.autocinfigure.StarterAutoConfigure

至此,我们的一个 Starter 代码部分就是完成了,下面将项目安装到本地 Maven 仓库中。

发布

在项目根目录执行 mvn install 进行打包安装。

测试

将 Starter 项目的依赖添加到我们自己的 SpringBoot 项目中

<dependency>
    <groupId>com.ysc</groupId>
    <artifactId>simple-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
 </dependency>

在application.yml 配置文件中添加配置信息:

example
  service
    enabled: true
    config: abc-des-dde,SSS-DRS-RE,SDR-SDFR-XXX

在本地使用JUnit进行代码测试

@Autowired
private StarterService starterService;

@Test
public void starterTest() {
    String[] splitArray = starterService.split(",");
    System.out.println(splitArray);
}

好,到这我们的一个自定义 Stater 就完成了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 java思维导图 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第一步创建一个 SpringBoot 项目,并添加下面两个依赖到 pom.xml 文件当中
  • 第二步编写我们的 Service 类
  • 第三步编写配置文件读取类
  • 第四步,编写AutoConfigure类 ,这步是关键点
    • 下面列举 SpringBoot 中的所有 @Conditional 注解及作用
    • 最后一步,在resources/META-INF/下创建spring.factories文件,并添加如下内容:
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档