咱们在使用Spring Cloud全家桶构建微服务应用时,常常能看到spring-boot-xxx-starter的依赖,像spring-boot-starter-web、spring-cloud-starter-feign、spring-boot-starter-test、mybatis-spring-boot-starter,仿佛只要带上starter的东西,你就拥有了这个组件的一切,包括全部的配置,引用类都搞定了,这样一个神奇的拿来就用的东西,是怎么实现的呢?咱们本身能不能把本身的工具包作成一个starter?java
groupId:这个标签的命名没作太多要求,基本上使用公司域名+项目名方式,如官方通常使用org.springframework.cloud,第三方通常用本身公司域名,如org.mybatis.spring.boot。
artifactId:这个标签的命名Spring官方给了建议命名方式,Spring官方本身发布的组件,命名方式是spring-boot-starter-xxx,xxx表示组件名称,像上文说起的spring-boot-starter-web和spring-cloud-starter-feign;第三方开发的组件,命名方式是xxx-spring-boot-starter,如mybatis-spring-boot-starter。git
以maven工程为例,Spring Boot Starter用多模块方式创建工程,工程内有autoconfigure模块和starter模块。
autoconfigure模块为自动配置模块,里面包含配置加载,所有的功能代码实现及须要引用的jar包,负责对内功能实现,全部的代码开发都在这个模块中完成。
starter模块提供自动配置模块的依赖,里面没有代码,是个空jar包,只有对autoconfigure模块的全部引用,是一个依赖集,它的目的是简化使用该组件时的依赖,只要添加starter模块,就能使用整个starter组件。github
咱们以经常使用的RocketMQ客户端组件为例,搭建一个本身定义的starter,RocketMQ是由阿里巴巴团队开发并捐赠给apache团队的优秀消息中间件,承受过历年双十一大促的考验。web
<groupId>com.hy.demo</groupId> <artifactId>rocketmq</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>rocketmq-spring-boot-autoconfigure</module> <module>rocketmq-spring-boot-starter</module> </modules> <dependencies> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.3.2</version> </dependency> <dependency> <groupId>org.apache.rocketmq</groupId> <artifactId>rocketmq-client</artifactId> <version>4.5.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.1.8.RELEASE</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> </dependency> </dependencies>
src目录下添加相应的工具类,如注解,配置类,接口等,略
添加定位配置侯选类,在META-INF/目录下新建spring.factories文件:spring
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.hy.demo.rocketmq.MQConfig
Spring Boot会检查你发布的jar中是否存在META-INF/spring.factories文件,自动配置类只能经过这种方式加载apache
只须要修改pom.xml文件便可:api
<parent> <artifactId>rocketmq</artifactId> <groupId>com.hy.demo</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>rocketmq-spring-boot-starter</artifactId> <dependencyManagement> <dependencies> <dependency> <groupId>com.hy.demo</groupId> <artifactId>rocketmq</artifactId> <version>1.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>com.hy.demo</groupId> <artifactId>rocketmq-spring-boot-autoconfigure</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
在IDEA上对该工程进行编译,打包,命令:mybatis
clean install -DskipTests=true
架构
四、打包部署完成后,在应用模块里添加该starter的依赖便可并发
<dependency> <groupId>com.hy.demo</groupId> <artifactId>rocketmq-spring-boot-starter</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
注:由于RocketMQ组件较为通用,目前提供基本的几种发送和接收消息的方式,支持事务消息,文章内就不一一解释代码功能,附上这次源码地址:
rocketmq-spring-boot-starter源码示例
@Import用来整合全部在@Configuration注解中定义的Bean配置;
@EventListener 事件监听,里面写的ContextStartedEvent,表示监听Spring上下文启动完成后的事件;
@Configuration至关于xml的beans标签;
@Bean标注在方法上,等同于xml的bean;
工程里定义了com.hy.demo.rocketmq.config.RocketMQAnnotationScan类对这两个注解进行扫描,利用注解@EventListener(ContextStartedEvent.class),监听Spring上下文初始化事件,而后从Spring容器内读取全部带这两个注解的类,把RocketMQ相关的配置信息加载进去,因为事务消息生产者类org.apache.rocketmq.client.producer.TransactionMQProducer的特殊性(它须要在初始化时注入TransactionListener监听类,与应用模块有必定耦合性),因此增长了一个Map集合存储应用模块内全部使用了@MQTransactionProducer注解的实例。
专一Java高并发、分布式架构,更多技术干货分享与心得,请关注公众号:Java架构社区