SpringBoot自定义starter

         Starter主要是在根据条件帮我们做Bean的自动装配。包括包扫描,加载,实例化和注册Bean,提供一种开箱即用的组件。
        SpringBoot存在很多 开箱即用的starter依赖,使得我们在开发业务代码的时候非常方便,无需关注框架的配置,只需要关注业务即可。

1、认识starter

    Starter是SpringBoot中的一个非常重要概念, starter 相当于一个模块,它能将模块所需的 依赖jar包-bean 整合起来并对模块内的bean根据条件进行自动配置。使用者只需要依赖相应功能的Starter,无需做过多的配置和依赖,SpringBoot就能自动扫描并加载相应的模块。比如我们使用spring-boot-strter-web就能使项目支持spring-mvc,自动导入加载依赖的spring-web/spring-webmvc等相关包及相关的配置。其 主要功能包括:
  • 自动将项目所需要的jar包-Bean自动装载注册到容器Map中;
  • 并且提供配置参数的入口及一些默认的参数配置, 遵循约定优于配置的原则;
  • 提供一个开箱即用的组件,一个集成化的模块;

2、starter的命名规范

推荐使用以下命名规约;
官方命名空间
  • 前缀:spring-boot-starter-{name}
  • 模式:spring-boot-starter- 模块名
  • 举例:spring-boot-strater-web/spring-boot-starter-actuator/spring-boot-starter-jdbc
 
自定义命名空间-非官方
  • 后缀:{name}-spring-boot-starter
  • 模式:模块-spring-boot-starter
  • 举例: mybaties-spring-boot-starter

3、自定义starter实践

如果有一些通用的服务接口,工具类,或者自定义的功能性注解,会被很多项目使用,那么我们就可以自己定义一个spring-boot-starter,来简化配置和使用,提高开发效率。

3.1、自定义starter项目模块的划分

SpringBoot 官方推荐的做法,将starter分为两个模块。
  • starter 启动器 模块:只用来做依赖包的导入:
  • autoconfig模块:专门用来自动配置模块的具体实现;
Starter模块依赖autoconfig模块。使用的时候直接引入starter即可。结构如下:
实例:编写一个用户信息服务组件,功能很简单,就是返回一个用户的信息。
我们目的就是让Starter自动帮我们把这个用户信息组件KingInfoService注入到spring容器中,其他的服务想用的时候就直接引入jar包即可;
第一步:建立 SpringBoot 工程-starter模块;直接引用configuration自动配置jar包即可,其它什么都不用做:
<groupId>com.beijing.starter</groupId>
<artifactId>king-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>

<!--启动器-->
<dependencies>

    <!--引入自动配置模块-->
    <dependency>
        <groupId>com.beijing.starter</groupId>
        <artifactId>king-spring-boot-starter-autoconfig</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </dependency>
</dependencies>

第二步:建立autoconfig模块:用来做服务的自动装载和配置的具体实现,编写需要自动加载的服务类;

//用户服务组件类
public class KingInfoService {

    KingInfoProperties kingInfoProperties;

    public KingInfoProperties getKingInfoProperties() {
        return kingInfoProperties;
    }

    public void setKingInfoProperties(KingInfoProperties kingInfoProperties) {
        this.kingInfoProperties = kingInfoProperties;
    }

    //返回一个用户信息,城市和工作时间可配置,只需要传入姓名即可;
    public KingInfo getKingInfo(String name ) {
        KingInfo kingInfo =  new KingInfo();
        kingInfo.setName(name);
        kingInfo.setPeriod(kingInfoProperties.getPeriod());
        kingInfo.setCity(kingInfoProperties.getCity());
        return kingInfo;

    }

}

用户信息entity类,其中用户信息的工作地点city和工作时间period是可以动态配置:

//用户信息entity类
@Data
public class KingInfo {

    private String name;
    private Integer period; //属性要求可动态配置
    private String city;    //属性要求可动态配置

}

第三步:编写用户属性配置元信息类-ConfigurationProperties

思考: 类似于DataSource和Mybaties都有自己的配置参数,那么这些bean配置需要的参数是如何规定并获取的呢?
虽然SpringBoot 帮我们自动导入了需要的jar包,使用了“约定大于配置”的原则给我设定了一些参数的原始值,但是,大多数情况下我们还需要根据自己的环境去改变一些参数的设置,所以这里就需要做到参数可以个性化设置,需要用到属性化配置文件。
//使配置文件可被spring扫描生效,自动配置
@ConfigurationProperties(prefix = KingInfoProperties.KING_PREFIX)
@Data
public class KingInfoProperties {

    public static final String KING_PREFIX = "king.info";
    private static final String default_name = "king";

    private String name = default_name;
    private Integer period = 3;
    private String city = "beijing";

    public KingInfoProperties() {
    }

    public KingInfoProperties(String name, Integer period,String city) {
        this.name = name;
        this.period = period;
        this.city = city;
    }

}

第四步:编写自动装载服务组件配置类-AutoConfiguration;实现服务组件KingInfoService的自动装配,让spring的IOC托管,提供开箱即用功能:

@Configuration //将这个类交给spring托管;
@EnableConfigurationProperties(KingInfoProperties.class) //开启了外部化属性配置
@AutoConfigureAfter(Init.class) //Init.class先加载;
@Import(OtherConfig.class) //导入其他的配置
@ConditionalOnProperty(prefix = KingInfoAutoConfiguration.prefix, value = "enabled", matchIfMissing = true)
public class KingInfoServiceAutoConfiguration {

    public static final String prefix = "king.info";

    @Autowired  //将设置的属性装载进来
    private KingInfoProperties kingInfoProperties;


    @Bean
    @Primary //自动给容器中注入KingInfoService服务组件
    @ConditionalOnMissingBean(KingInfo.class)
    public KingInfoService kingInfoService() {
        KingInfoService kingInfoService = new KingInfoService();
        kingInfoService.setKingInfoProperties(kingInfoProperties);
        return kingInfoService;
    }
}

第五步:配置自动发现配置文件-EnableAutoConfiguration

思考:编写的Bean类是如何让SpringBoot自动扫描和加载到内存的呢?
    写完了上面的这些配置类后最重要的是要使这些配置类能被Spring启动的时候自动加载管理,那么这个加载时机是什么时候呢?
     SpringFactoriesLoader自动扫描加载
    这里用到了SpringFactoriesLoader这个工具类。在SpringBoot的启动原理也有讲到,这里不过多的讲解了。过程主要是:在tomcat启动的时候,会优先去检查寻找classpath/META-INF/spring.factories下需要加载的class类,找到这些类的字节码,然后把它先加载到内存,供后面的服务进行调用。
设置自动装配类的扫描路径key-value的设置。
spring.factories文件的配置, key的值是@EnableAutoConfiguration注解的配置类路径,固定不变;
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.beijing.starter.config.KingInfoServiceAutoConfiguration

整体的目录结构:

至此,我们的starter就已经编写完成了。
第六步:打包发布及使用
    编译,安装到仓库,或者发布到私服,其他的服务直接下载引用这个启动器starter—jar包,就可以使用我们用户服务组件了。
<dependency>
    <groupId>com.beijing.starter</groupId>
    <artifactId>king-spring-boot-starter</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

具体的配置属性city和period我们也可以在appliction.preperties中进行设置,其他的一些starter组件的实现原理和它都是一样的。

4、小结

    开发一个自己的spring-boot-starter的具体步骤:具体步骤:
  1. 建立工程,创建xxx-spring-boot-starter, xxx-spring-boot-autoconfigure模块,导入依赖的第三方jar包;
  2. 编写属性配置元信息类;
  3. 编写自动配置类;
  4. 配置自动发现配置文件:META-INF/spring.factories;
  5. 打包发布;
 
 
 
参考文件:
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值