上篇文章《每天用SpringBoot,它的自动装配原理却说不出来》咱们有说springBoot
的自动装配怎么实现的(建议最好先看下篇文章,由于先后有关系),这篇文章的话咱们就本身来实现一个SpringBoot
的 starter
吧。废话很少说咱们仍是直入主题吧。
什么是Spring Boot Starter
呢?咱们直接来看看官网是怎么介绍的吧。html
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.java
纳尼,一大堆的英文,这还有兴趣接着往下看吗?是否是看到这直接退出了。都到门口了,不进来喝杯茶再走嘛?看都看到这了仍是接着继续往下看吧。咱们先不解释这一段话是什么意思,咱们能够看看starter
的出现给咱们解决了什么问题。
咱们仍是以上述官网的例子来进行说明好比说咱们须要在Spring
中适应JPA
来操做数据库。
在没有springBoot-starter
以前,咱们须要引入jpa
的步骤git
maven
引入jdbc的依赖、以及jpa相关的各类依赖jpa
相关的配置文件jar
包冲突啊,这个jar
包下载不下来,缺乏某个jar
包。jpa
遇到的问题,以及整合的步骤都一一的详细记录下来。方便下次在须要整合jpa
的时候直接copy
就行了。starter
以前是否是都是这么玩的。这样的缺点是否是也很是显著,好比过程复杂、须要不停的粘贴复制(不过这是程序员常常干的事情了,也不在意多一两次了)、整合其它组件到本身的项目变的困难,效率低下。这也就形成了996
的程序员比较多了(晚上就不可以回去69
了)。咱们能够看下SpringBoot
如今都为咱们提供有哪些starter
,我这边这截图了部分starter
,更多的请点击https://github.com/spring-projects/spring-boot/tree/master/spring-boot-project/spring-boot-starters
starter
的实现:虽然咱们每一个组件的starter
实现各有差别,可是它们基本上都会使用到两个相同的内容:ConfigurationProperties
和AutoConfiguration
。由于Spring Boot
提倡“约定大于配置”这一理念,因此咱们使用ConfigurationProperties
来保存咱们的配置,而且这些配置均可以有一个默认值,即在咱们没有主动覆写原始配置的状况下,默认值就会生效。除此以外,starter
的ConfigurationProperties
还使得全部的配置属性被汇集到一个文件中(通常在resources
目录下的application.properties
),这样咱们就告别了Spring
项目中XML
地狱。
starter
的出现帮把咱们把各类复杂的配置都封装起来了,让咱们真正的能够达到了开箱即用。不只下降了咱们使用它的门槛,而且还大大提升了咱们的开发效率。正如前面所说《SpringBoot自动装配》让咱们有更多的时间去陪女友。程序员
若是你快有孩子了,出生前你比较急的必定是起个名字。孩子的姓名标识着你和你爱人的血统,必定不会起隔壁老王的姓氏,确定会招来异样的眼光。在maven
中,groupId
表明着姓氏,artifactId
表明着名字。Spring Boot
也是有一个命名的建议的。因此名字是不可以随随便便取得,能够按照官方的建议来取。github
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.spring
大概意思是
官方的 starter
的命名格式为 spring-boot-starter-{xxxx}
好比spring-boot-starter-activemq
第三方咱们本身的命名格式为 {xxxx}-spring-boot-starter
。好比mybatis-spring-boot-starter
。
若是咱们忽略这种约定,是否是会显得咱们写的东西不够“专业“。数据库
下面咱们就来实现一个自定义的发送短信的starter,命名为sms-spring-boot-starter
。json
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>
发短信咱们须要配置一些帐号信息,不一样的短信供应商,帐户信息是不同的,因此咱们须要定义一个XXXXProperties
来自动装配这些帐户信息。下面咱们就以腾讯云和阿里云两家供应商为例;springboot
@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
的属性信息就能够了。 好比:mybatis
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类的成员属性来生成的。
@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; } }
starter
集成应用有两种方式:
SpringBoot
的SPI
的机制来去加载咱们的starter。咱们须要在META-INF
下新建一个spring.factories
文件key
为org.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
命令就能够了。
若是须要部署到公司的仓库话,这个就不说了。
6. 新建一个新的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
的出现,让咱们项目中集成其余组件变得简单。它把简单给了别人,把复杂留给了本身。“牺牲小我,成就大我”的思想仍是值得学习的。平时咱们工做中,好比要开发一个组件、或者一个工具类,也应该尽量的让使用方能够作到无脑使用,不要搞的太复杂,又能让使用者能够灵活扩展。