Java essay Java essay
首页
  • Java基础
  • Java进阶
  • 设计模式
  • 多线程
  • Java你不知道的小事
  • Spring初识
  • Spring进阶
  • SpringBoot基础
  • SpringBoot进阶
  • 什么是微服务
  • SpringCloud全家桶
  • Dubbo
  • SpringCloud Alibaba
  • Vue
  • 小程序
  • 博客搭建
  • 数据库
  • python
  • 大数据
  • 性能分析优化
  • 中间件
  • 云原生
  • 面试
  • 外卖霸王餐
  • 打工人的带饭生活
  • 30岁我该怎么办
友链
关于我
GitHub (opens new window)

Mr.Fire

全栈工程师
首页
  • Java基础
  • Java进阶
  • 设计模式
  • 多线程
  • Java你不知道的小事
  • Spring初识
  • Spring进阶
  • SpringBoot基础
  • SpringBoot进阶
  • 什么是微服务
  • SpringCloud全家桶
  • Dubbo
  • SpringCloud Alibaba
  • Vue
  • 小程序
  • 博客搭建
  • 数据库
  • python
  • 大数据
  • 性能分析优化
  • 中间件
  • 云原生
  • 面试
  • 外卖霸王餐
  • 打工人的带饭生活
  • 30岁我该怎么办
友链
关于我
GitHub (opens new window)
  • Spring

  • Spring进阶

  • SpringBoot基础

    • SpringBoot初识
    • SpringBoot基础
    • SpringBoot集成MyBatis
    • SpringBoot自定义Starter
      • SpingBoot常用工具类
    • SpringBoot进阶

    • Spring
    • SpringBoot基础
    Mr.Fire
    2022-08-06
    目录
    Starter 命名规范
    手写一个 starter 组件
    测试
    总结

    SpringBoot自定义Starter

    • Starter 命名规范
    • 手写一个 starter 组件
    • 测试
    • 总结

    # Starter 命名规范

    什么是 Starter,比如spring-boot-starter-data-redis就是一个标准的官方 Starter 组件。Starter 内部定义了相关 jar 包的依赖,而我们不需要一个一个去引入相关 jar,实现了 bean 自动装配,自动声明并且加载 properties 文件属性配置。

    命名规范:

    • 官方:spring-boot-starter-模块名称
    • 自定义:模块名称-spring-boot-starter

    # 手写一个 starter 组件

    基于前面所讲自动装配原理,我们从 0 到 1 写一个自定义的 Starter 组件来加深大家对自动装配的理解。下面是基于消息中间件 RabbitMQ 写一个自定义 Starter 组件,不了解 RabbitMQ 的朋友可以参阅我之前的文章,到具体的客户端使用该组件详细步骤。

    1. 创建一个名为 mq-spring-boot-starter 的 maven 项目 目录结构:

    添加 jar 包依赖,pom 文件中引入 spring-rabbit(spring 对 RabbitMQ 的一个封装):

     <dependency>
         <groupId>org.springframework.amqp</groupId>
         <artifactId>spring-rabbit</artifactId>
         <version>2.3.10</version>
         <scope>compile</scope>
     </dependency>
    
    1
    2
    3
    4
    5
    6
    1. 定义属性类

    该属性类配置 RabbitMQ 的 IP、端口、用户名、密码等信息。由于只是一个简单的 Demo,只定义了一些简单的参数。前缀为 fire.mq,对应 properties/yml 中的属性。

    /**
     * @author Mr.Fire 
     * @date 2021/8/15 17:35
     * @desc
     */
    @ConfigurationProperties(prefix = "fire.mq")
    public class RabbitMqProperties {
    
        private String address = "localhost";
    
        private int port = 5672;
    
        private String userName;
    
        private String password;
    
        ...
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    1. 定义配置类
    • 通过 @Configuration 声明为一个配置类
    • @EnableConfigurationProperties(RabbitMqProperties.class):导入属性类
    • @Bean 注解方式上声明一个 connectionFactory 的 bean 对象,设置用户名密码等
    • 通过 FireRabbitTemplate 的构造方法传入 connectionFactory
    • @ConditionalOnClass:表示一个条件,当前 classpath 下有这个 class,才会实例化一个 Bean

    注:这里的 FireRabbitTemplate 为我自定义的一个类,继承自了 RabbitTemplate,下面步骤有写。

    /**
     * @author Mr.Fire 
     * @date 2021/8/15 17:40
     * @desc
     */
    @Configuration
    @EnableConfigurationProperties(RabbitMqProperties.class)
    public class RabbitMqConfig {
    
        @Bean
        @ConditionalOnClass(ConnectionFactory.class)
        FireRabbitTemplate fireRabbitTemplate(ConnectionFactory connectionFactory) {
            FireRabbitTemplate rabbitTemplate = new FireRabbitTemplate(connectionFactory,"fireMQ");
            //数据转换为 json 存入消息队列
            rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
            return rabbitTemplate;
        }
        
        @Bean
        ConnectionFactory connectionFactory(RabbitMqProperties rabbitMqProperties){
            CachingConnectionFactory connectionFactory = new CachingConnectionFactory("localhost");
            connectionFactory.setHost(rabbitMqProperties.getAddress());
            connectionFactory.setPort(rabbitMqProperties.getPort());
            connectionFactory.setUsername(rabbitMqProperties.getUserName());
            connectionFactory.setPassword(rabbitMqProperties.getPassword());
            return connectionFactory;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    1. 自定义的 RabbitTemplate

    定义一个有 name 的 RabbitTemplate,继承自 RabbitTemplate,通过名字测试可以直观看到效果。

    注:RabbitTemplate 是 Spring 对 RabbitMQ 的一个封装好的模板接口,类似于 RedisTemplate。

    /**
     * @author Mr.Fire
     * @date 2021/8/15 17:42
     * @desc
     */
    public class FireRabbitTemplate extends RabbitTemplate {
    
        private String name="fireMQ";
    
    
        public FireRabbitTemplate(ConnectionFactory connectionFactory,String name) {
            super(connectionFactory);
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    1. 关键一步,在 resources 目录下新建 spring.factories 文件,key-value 形式配置写好的 Config 类。使 Spring Boot 可以扫描到文件完成自动装配。
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.fire.mq.rabbitmq.RabbitMqConfig
    
    1
    2

    至此,一个非常简单的自定义 Starer 组件已经完成。我们只需要安装到本地仓库,其他项目就可以引用该组件了。

    1. 执行命令 mvn install 到本地仓库。

    注:安装前需要把 spring-boot-maven-plugin 给去掉。

    # 测试

    接下来我们新建一个测试工程来引入我们写好的 Starter 组件,测试一下效果。

    1. 新建一个简单的测试工程 starter-cilent,目录结构如下:

    1. 引入自定义的 Starter:
    <dependency>
       <groupId>com.fire</groupId>
       <artifactId>mq-spring-boot-starter</artifactId>
       <version>0.0.1-SNAPSHOT</version>
    </dependency>
    
    1
    2
    3
    4
    5
    1. 编写测试代码

    这里写一个 Web 接口用来模拟发消息,发到对应的 helloQueue 队列中,监听这个队列的消费者就能消费这条消息。

    定义 rest 接口:注入自定义 Starter 组件中的 FireRabbitTemplate 模板接口类,调用发消息的方法。

    /**
     * @author Mr.Fire
     * @date 2021/8/15 17:48
     * @desc
     */
    @RestController
    public class MqRestController {
    
        @Autowired
        FireRabbitTemplate rabbitTemplate;
        
        @GetMapping("/send")
        public String sendMsg(){
            String msg = "这是一条来自"+rabbitTemplate.getName()+"的消息!";
            rabbitTemplate.convertAndSend("helloQueue",msg);
            return "success";
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    定义队列:

    @Configuration
    public class HelloQueue {
    
        @Bean
        public org.springframework.amqp.core.Queue queue() {
            return new org.springframework.amqp.core.Queue("helloQueue");
        }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8

    定义消费者,监听 helloQueue 队列,并打印收到的消息。

    @Configuration
    public class Consumer {
    
        @RabbitListener(queues = "helloQueue")
        @RabbitHandler
        public void receive(String msg) {
            System.out.println("Consumer 收到消息:" + msg);
        }
    
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    1. 配置文件 appliction.properties

    这里默认本地已经安装 RabbitMQ,需要的朋友可以看我的前一篇文章。

    fire.mq.address=localhost
    fire.mq.port=5672
    fire.mq.username=guest
    fire.mq.password=guest
    server.port=8081
    
    1
    2
    3
    4
    5
    1. 启动测试

    浏览器输入 http://localhost:8081/send,看控制台输出:

    这说明自己写的 Starter 组件已经生效,成功收到“fireMq”发来的消息。

    # 总结

    通过手写一个简单的自定义 Starter 组件加深对自动装配的理解。有需要的朋友可以动手写一个Starter组件进行加深理解。


    案例demo:

    mq-spring-boot-starter: https://gitee.com/firegitspace/mq-spring-boot-starter.git (opens new window)

    starter-cilent: https://gitee.com/firegitspace/starter-cilent.git (opens new window)

    #SpringBoot
    最后更新时间: 2024/03/15, 17:35:22
    SpringBoot集成MyBatis
    SpingBoot常用工具类

    ← SpringBoot集成MyBatis SpingBoot常用工具类→

    最近更新
    01
    SuperBuilder
    12-29
    02
    30岁我该怎么办
    12-29
    03
    关于存钱
    12-29
    更多文章>
    Theme by Vdoing | Copyright © 2021-2025 Mr.Fire | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式