zoukankan      html  css  js  c++  java
  • 使用Spring-boot-starter标准改造项目内的RocketMQ客户端组件

    一、背景介绍

    我们在使用Spring Cloud全家桶构建微服务应用时,经常能看到spring-boot-xxx-starter的依赖,像spring-boot-starter-web、spring-cloud-starter-feign、spring-boot-starter-test、mybatis-spring-boot-starter,仿佛只要带上starter的东西,你就拥有了这个组件的一切,包括所有的配置,引用类都搞定了,这样一个神奇的拿来就用的东西,是怎么实现的呢?我们自己能不能把自己的工具包做成一个starter?

    二、Spring Boot Starter组件规范

    • 命名规范

    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。

    • 工程规范

    以maven工程为例,Spring Boot Starter用多模块方式建立工程,工程内有autoconfigure模块和starter模块。
    autoconfigure模块为自动配置模块,里面包含配置加载,全部的功能代码实现及需要引用的jar包,负责对内功能实现,所有的代码开发都在这个模块中完成。
    starter模块提供自动配置模块的依赖,里面没有代码,是个空jar包,只有对autoconfigure模块的所有引用,是一个依赖集,它的目的是简化使用该组件时的依赖,只要添加starter模块,就能使用整个starter组件。

    三、案例实战

    我们以常用的RocketMQ客户端组件为例,搭建一个自己定义的starter,RocketMQ是由阿里巴巴团队开发并捐赠给apache团队的优秀消息中间件,承受过历年双十一大促的考验。

    1. 创建一个Maven工程,增加两个模块rocketmq-spring-boot-autoconfigure和rocketmq-spring-boot-starter,这里使用的RocketMQ版本为4.5.2,主pom.xml节选如下:
    <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>
    
    1. autoconfigure模块开发
      src目录下添加相应的工具类,如注解,配置类,接口等,略
      添加定位配置侯选类,在META-INF/目录下新建spring.factories文件:
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.hy.demo.rocketmq.MQConfig
    

    Spring Boot会检查你发布的jar中是否存在META-INF/spring.factories文件,自动配置类只能通过这种方式加载

    1. starter模块开发
      只需要修改pom.xml文件即可:
    <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上对该工程进行编译,打包,命令:

    clean install -DskipTests=true

    4、打包部署完成后,在应用模块里添加该starter的依赖即可

    <dependency>
       <groupId>com.hy.demo</groupId>
       <artifactId>rocketmq-spring-boot-starter</artifactId>
       <version>1.0-SNAPSHOT</version>
    </dependency>
    

    注:因为RocketMQ组件较为通用,目前提供基本的几种发送和接收消息的方式,支持事务消息,文章内就不一一解释代码功能,附上此次源码地址:

    rocketmq-spring-boot-starter源码示例

    四、知识点梳理

    1. Spring的几个注解:
      @Import用来整合所有在@Configuration注解中定义的Bean配置;
      @EventListener 事件监听,里面写的ContextStartedEvent,表示监听Spring上下文启动完成后的事件;
      @Configuration相当于xml的beans标签;
      @Bean标注在方法上,等同于xml的bean;

    2. 自定义注解@MQConsumer和注解@MQTransactionProducer是如何起作用的?
      工程里定义了com.hy.demo.rocketmq.config.RocketMQAnnotationScan类对这两个注解进行扫描,利用注解@EventListener(ContextStartedEvent.class),监听Spring上下文初始化事件,然后从Spring容器内读取所有带这两个注解的类,把RocketMQ相关的配置信息加载进去,由于事务消息生产者类org.apache.rocketmq.client.producer.TransactionMQProducer的特殊性(它需要在初始化时注入TransactionListener监听类,与应用模块有一定耦合性),所以增加了一个Map集合存储应用模块内所有使用了@MQTransactionProducer注解的实例。
      专注Java高并发、分布式架构,更多技术干货分享与心得,请关注公众号:Java架构社区
      Java架构社区

  • 相关阅读:
    184. Department Highest Salary【leetcode】sql,join on
    181. Employees Earning More Than Their Managers【leetcode】,sql,inner join ,where
    178. Rank Scores【leetcode】,sql
    177. Nth Highest Salary【leetcode】,第n高数值,sql,limit,offset
    176. Second Highest Salary【取表中第二高的值】,sql,limit,offset
    118. Pascal's Triangle【LeetCode】,java,算法,杨辉三角
    204. Count Primes【leetcode】java,算法,质数
    202. Happy Number【leetcode】java,hashSet,算法
    41. First Missing Positive【leetcode】寻找第一个丢失的整数,java,算法
    删除
  • 原文地址:https://www.cnblogs.com/huangying2124/p/11696226.html
Copyright © 2011-2022 走看看