乐趣区

关于spring:保姆级教程手把手教你实现一个SpringBoot的starter

引言

上篇文章《天天用 SpringBoot,它的主动拆卸原理却说不进去》咱们有说 springBoot 的主动拆卸怎么实现的(倡议最好先看下篇文章,因为前后有关系),这篇文章的话咱们就本人来实现一个 SpringBootstarter吧。废话不多说咱们还是直入主题吧。

什么是 Spring Boot Starter 呢? 咱们间接来看看官网是怎么介绍的吧。

Starters are a set of convenient dependency descriptors that you can include in your application. You get a one-stop shop for all the Spring and related technologies that you need without having to hunt through sample code and copy-paste loads of dependency descriptors. For example, if you want to get started using Spring and JPA for database access, include the spring-boot-starter-data-jpa dependency in your project.

纳尼, 一大堆的英文,这还有趣味接着往下看吗?是不是看到这间接退出了。都到门口了,不进来喝杯茶再走嘛?看都看到这了还是接着持续往下看吧。咱们先不解释这一段话是什么意思,咱们能够看看 starter 的呈现给咱们解决了什么问题。
咱们还是以上述官网的例子来进行阐明比如说咱们须要在 Spring 中适应JPA 来操作数据库。
在没有 springBoot-starter 之前,咱们须要引入 jpa 的步骤

  • 通过maven 引入 jdbc 的依赖、以及 jpa 相干的各种依赖
  • 编写 jpa 相干的配置文件
  • 网上各种查问找材料进行调试,调试的过程对于老手可能会有点奔溃会遇到各种奇奇怪怪的问题,jar包抵触啊,这个 jar 包下载不下来,短少某个 jar 包。
  • 终于在经验含辛茹苦,哼次哼次的解决各种问题之后终于把我的项目跑起来了,而后把这次整合 jpa 遇到的问题,以及整合的步骤都一一的具体记录下来。不便下次在须要整合 jpa 的时候间接 copy 就好了。

咱们以前在没有 starter 之前是不是都是这么玩的。这样的毛病是不是也十分显著,比方过程简单、须要不停的粘贴复制(不过这是程序员常常干的事件了,也不在乎多一两次了)、整合其它组件到本人的我的项目变的艰难,效率低下。这也就造成了 996 的程序员比拟多了 (早晨就不可能回去69 了)。

SpringBoot Starter 的呈现

咱们能够看下 SpringBoot 当初都为咱们提供有哪些starter,我这边这截图了局部starter,更多的请点击 https://github.com/spring-pro…

starter 的实现:尽管咱们每个组件的 starter 实现各有差别,然而它们基本上都会应用到两个雷同的内容:ConfigurationPropertiesAutoConfiguration。因为Spring Boot 提倡“约定大于配置 ”这一理念,所以咱们应用ConfigurationProperties 来保留咱们的配置,并且这些配置都能够有一个默认值,即在咱们没有被动覆写原始配置的状况下,默认值就会失效。除此之外,starterConfigurationProperties 还使得所有的配置属性被汇集到一个文件中(个别在 resources 目录下的 application.properties),这样咱们就辞别了Spring 我的项目中 XML 天堂。
starter的呈现帮把咱们把各种简单的配置都封装起来了,让咱们真正的能够达到了开箱即用。不仅升高了咱们应用它的门槛,并且还大大提高了咱们的开发效率。正如后面所说《SpringBoot 主动拆卸》让咱们有更多的工夫去陪女朋友。

实现本人的 SpringBoot Starter

命名标准

如果你快有孩子了,出世前你比拟急的肯定是起个名字。孩子的姓名标识着你和你爱人的血统,肯定不会起隔壁老王的姓氏,必定会招来同样的眼光。在 maven 中,groupId代表着姓氏,artifactId代表着名字。Spring Boot也是有一个命名的倡议的。所以名字是不可能随随便便获得,能够依照官网的倡议来取。

What’s in a name
All official starters follow a similar naming pattern; spring-boot-starter-, where is a particular type of application. This naming structure is intended to help when you need to find a starter. The Maven integration in many IDEs lets you search dependencies by name. For example, with the appropriate Eclipse or STS plugin installed, you can press ctrl-space in the POM editor and type“spring-boot-starter”for a complete list.
As explained in the“Creating Your Own Starter”section, third party starters should not start with spring-boot, as it is reserved for official Spring Boot artifacts. Rather, a third-party starter typically starts with the name of the project. For example, a third-party starter project called thirdpartyproject would typically be named thirdpartyproject-spring-boot-starter.

大略意思是
官网的 starter 的命名格局为 spring-boot-starter-{xxxx} 比方 spring-boot-starter-activemq
第三方咱们本人的命名格局为 {xxxx}-spring-boot-starter。比方 mybatis-spring-boot-starter
如果咱们疏忽这种约定,是不是会显得咱们写的货色不够“业余“。

自定义一个 Starter

上面咱们就来实现一个自定义的发送短信的 starter,命名为sms-spring-boot-starter

  1. 引入pom
 <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>
          <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.18</version>
            <scope>provided</scope>
        </dependency>
  1. 编写配置文件

    发短信咱们须要配置一些账号信息,不同的短信供应商,账户信息是不一样的,所以咱们须要定义一 个 XXXXProperties 来主动拆卸这些账户信息。上面咱们就以腾讯云和阿里云两家供应商为例;

@ConfigurationProperties(prefix = "sms")
@Data
public class SmsProperties {private SmsMessage aliyun = new SmsMessage();

    private SmsMessage tencent = new SmsMessage();

    @Data
    public static class SmsMessage{


        /**
         * 用户名
         */
        private String userName;

        /**
         * 明码
         */
        private String passWord;

        /**
         * 秘钥
         */
        private String sign;

        /**
         *
         */
        private String url;

        @Override
        public String toString() {
            return "SmsMessage{" +
                    "userName='" + userName + '\'' +
                    ", passWord='" + passWord + '\'' +
                    ", sign='" + sign + '\'' +
                    ", url='" + url + '\'' +
                    '}';
        }
    }
}

如果须要在其余我的项目中应用发送短信性能的话,咱们只须要在配置文件(application.yml)中配置SmsProperties 的属性信息就能够了。比方:

sms:
  aliyun:
    pass-word: 12345
    user-name: java 金融
    sign: 阿里云
    url: http://aliyun.com/send
  tencent:
    pass-word: 6666
    user-name: java 金融
    sign: 腾讯云
    url: http://tencent.com/send

还记的 @ConfigurationProperties 注解外面是不是有个 prefix 属性,咱们配置的这个属性是sms,配置这个的次要一个作用的话是次要用来区别各个组件的参数。这里有个小知识点须要留神下当咱们在配置文件输出sms 咱们的 idea 会提醒这个 sms 有哪些属性能够配置,以及每个属性的正文都有标记,倡议的话正文还是写英文,这样会显得你比拟业余。

这个提醒的话,是须要引入上面这个 jar 的。

  <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

引入这个 jar 之后,咱们编译之后就会在 META-INF 文件夹上面生成一个 spring-configuration-metadata.json 的文件。

咱们能够看到这个文件其实 是依据 SmsProperties 类的成员属性来生成的。

  1. 而后在编写短信主动配置类:
@EnableConfigurationProperties(value = SmsProperties.class)
@Configuration
public class SmsAutoConfiguration  {
    /**
     *  阿里云发送短信的实现类
     * @param smsProperties
     * @return
     */
    @Bean
    public AliyunSmsSenderImpl aliYunSmsSender(SmsProperties smsProperties){return new AliyunSmsSenderImpl(smsProperties.getAliyun());
    }
    /**
     * 腾讯云发送短信的实现类
     * @param smsProperties
     * @return
     */
    @Bean
    public TencentSmsSenderImpl tencentSmsSender(SmsProperties smsProperties){return new TencentSmsSenderImpl(smsProperties.getTencent());
    }
}

编写咱们的发送短信实现类:

public class AliyunSmsSenderImpl implements SmsSender {

    private SmsMessage smsMessage;

    public AliyunSmsSenderImpl(SmsMessage smsProperties) {this.smsMessage = smsProperties;}

    @Override
    public boolean send(String message) {System.out.println(smsMessage.toString()+"开始发送短信 ==》短信内容:"+message);
        return true;
    }
}
  1. 让 starter 失效

starter集成利用有两种形式:

  • 被动失效

咱们首先来看下咱们相熟的形式,通过 SpringBootSPI的机制来去加载咱们的 starter。咱们须要在 META-INF 下新建一个 spring.factories 文件 keyorg.springframework.boot.autoconfigure.EnableAutoConfiguration,value是咱们的 SmsAutoConfiguration 全限定名( 记得去除前后的空格,否则会不失效)。

  • 被动失效

starter 组件集成到咱们的 Spring Boot 利用时须要被动申明启用该 starter 才失效,通过自定义一个 @Enable 注解而后在把主动配置类通过 Import 注解引入进来。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({SmsAutoConfiguration.class})
public @interface EnableSms {}

应用的时候须要在启动类下面开启这个注解。

5.打包,部署到仓库
如果是本地的话,间接通过mvn install 命令就能够了。
如果须要部署到公司的仓库话,这个就不说了。

  1. 新建一个新的 SpringBoot 我的项目引入咱们刚写的starter
 <dependency>
            <groupId>com.workit.sms</groupId>
            <artifactId>sms-spring-boot-starter</artifactId>
            <version>0.0.1-SNAPSHOT</version>
      </dependency>

在我的项目配置文件配上短信账号信息

测试代码

@SpringBootApplication
@EnableSms
public class AutoconfigApplication {public static void main(String[] args) {ConfigurableApplicationContext applicationContext = SpringApplication.run(AutoconfigApplication.class, args);
        AliyunSmsSenderImpl aliyunSmsSender = applicationContext.getBean(AliyunSmsSenderImpl.class);
        aliyunSmsSender.send("用阿里云发送短信");
        TencentSmsSenderImpl tencentSmsSender = applicationContext.getBean(TencentSmsSenderImpl.class);
        tencentSmsSender.send("用腾讯云发送短信");
    }

运行后果:

SmsMessage{userName='java 金融', passWord='12345', sign='阿里云', url='http://aliyun.com/send'}开始发送短信 ==》短信内容:用阿里云发送短信
SmsMessage{userName='java 金融', passWord='6666', sign='腾讯云', url='http://tencent.com/send'}开始发送短信 ==》短信内容:用腾讯云发送短信

至此的话咱们自定义的一个 starter 就曾经实现了,这个 starter 只是一个演示的 demo,代码有点毛糙, 我的项目构造也有点问题。重点看下这个实现原理就好。连忙动动小手去实现一个本人的starter 吧。

总结

  • SpringBoot starter的呈现,让咱们我的项目中集成其余组件变得简略。它把简略给了他人,把简单留给了本人。“就义小我,成就大我”的思维还是值得学习的。平时咱们工作中,比方要开发一个组件、或者一个工具类,也应该尽可能的让应用方能够做到无脑应用,不要搞的太简单,又能让使用者能够灵便扩大。

完结

  • 因为本人满腹经纶,难免会有纰漏,如果你发现了谬误的中央,还望留言给我指出来, 我会对其加以修改。
  • 如果你感觉文章还不错,你的转发、分享、赞叹、点赞、留言就是对我最大的激励。
  • 感谢您的浏览, 非常欢送并感谢您的关注。


站在伟人的肩膀上摘苹果:
https://www.cnblogs.com/tjudz…
https://blog.springlearn.cn/p…

退出移动版