1. 1 不可撤销
  2. 2 小年兽 程嘉敏
  3. 3 手放开 李圣杰
  4. 4 迷人的危险3(翻自 dance flow) FAFA
  5. 5 山楂树之恋 程佳佳
  6. 6 summertime cinnamons / evening cinema
  7. 7 不谓侠(Cover 萧忆情Alex) CRITTY
  8. 8 神武醉相思(翻自 优我女团) 双笙
  9. 9 空山新雨后 音阙诗听 / 锦零
  10. 10 Wonderful U (Demo Version) AGA
  11. 11 广寒宫 丸子呦
  12. 12 陪我看日出 回音哥
  13. 13 春夏秋冬的你 王宇良
  14. 14 世界が终わるまでは… WANDS
  15. 15 多想在平庸的生活拥抱你 隔壁老樊
  16. 16 千禧 徐秉龙
  17. 17 我的一个道姑朋友 双笙
  18. 18 大鱼  (Cover 周深) 双笙
  19. 19 霜雪千年(Cover 洛天依 / 乐正绫) 双笙 / 封茗囧菌
  20. 20 云烟成雨(翻自 房东的猫) 周玥
  21. 21 情深深雨濛濛 杨胖雨
  22. 22 Five Hundred Miles Justin Timberlake / Carey Mulligan / Stark Sands
  23. 23 斑马斑马 房东的猫
  24. 24 See You Again Wiz Khalifa / Charlie Puth
  25. 25 Faded Alan Walker / Iselin Solheim
  26. 26 Natural J.Fla
  27. 27 New Soul Vox Angeli
  28. 28 ハレハレヤ(朗朗晴天)(翻自 v flower) 猫瑾
  29. 29 像鱼 王贰浪
  30. 30 Bye Bye Bye Lovestoned
  31. 31 Blame You 眠 / Lopu$
  32. 32 Believer J.Fla
  33. 33 书信 戴羽彤
  34. 34 柴 鱼 の c a l l i n g【已售】 幸子小姐拜托了
  35. 35 夜空中最亮的星(翻自 逃跑计划) 戴羽彤
  36. 36 慢慢喜欢你 LIve版(翻自 莫文蔚) 戴羽彤
  37. 37 病变(翻自 cubi) 戴羽彤
  38. 38 那女孩对我说 (完整版) Uu
  39. 39 绿色 陈雪凝
  40. 40 月牙湾 LIve版(翻自 F.I.R.) 戴羽彤
夜空中最亮的星(翻自 逃跑计划) - 戴羽彤
00:00 / 04:10

夜空中最亮的星 能否听清

那仰望的人 心底的孤独和叹息

夜空中最亮的星 能否记起

那曾与我同行 消失在风里的身影

我祈祷拥有一颗透明的心灵

和会流泪的眼睛

给我再去相信的勇气

越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请指引我靠近你

夜空中最亮的星 是否知道

那曾与我同行的身影 如今在哪里

夜空中最亮的星 是否在意

是等太阳先升起 还是意外先来临

我宁愿所有痛苦都留在心底

也不愿忘记你的眼睛

哦 给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行 哒~

我祈祷拥有一颗透明的心灵

和会流泪的眼睛 哦

给我再去相信的勇气

哦 越过谎言去拥抱你

每当我找不到存在的意义

每当我迷失在黑夜里

噢喔喔 夜空中最亮的星

请照亮我向前行

编写你的第一个spring-boot-starter

前言

我们在使用spring-boot的时候,会经常用到各种各样的starter,比如spring-boot-starter-web,不知道各个小伙伴有没有好奇过这些starter到底是怎么定义出来的,反正我好奇过,但是一直没有去深入了解过,最近在项目开发中,我们需要封装一个mq的通用组件,有个同事就封装成一个starter,然后就勾起了学习和研究的好奇心,所以想着趁今天的时间做一个小demo,写一个属于自己的starter

下面我们就来看下具体如何实现。

手写spring-boot-starter

创建项目

首先我们要创建一个maven项目,根据自己的需要引入项目依赖,因为我们要写的是sprin-bootstarter,所以spring-boot-starter的依赖必须引入:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
    <version>2.3.7.RELEASE</version>
    <scope>compile</scope>
    <optional>true</optional>
</dependency>

因为starter的核心其实是配置类,而这些配置类注解都在spring-boot-starter包下。创建完成后的项目结构如下:

我的这个组件是一个通用的消息发送组件,所以我还引入activemq的相关包,对demo感兴趣的小伙伴可以直接去看项目源码,文末有地址。

配置类

这里就是starter的核心了,这里我们要对组件进行配置,主要是bean的注入:

@Configuration
@EnableJms
@ConditionalOnClass(JmsMessageServiceImpl.class)
public class AutoConfigurationClass {

    @Value("${spring.activemq.broker-url}")
    private String brokerURL;

    @ConditionalOnMissingBean
    @Bean
    public JmsMessageService jmsMessageService(JmsMessagingTemplate jmsTemplate){
        return new JmsMessageServiceImpl(jmsTemplate);
    }

    @ConditionalOnMissingBean
    @Bean
    public JmsMessagingTemplate jmsMessagingTemplate(ConnectionFactory connectionFactory) {
        return new JmsMessagingTemplate(connectionFactory);
    }

    @ConditionalOnMissingBean
    @Bean
    public ConnectionFactory connectionFactory() {
        return new ActiveMQConnectionFactory(brokerURL);
    }
}

前面说了我的组件是通用的消息组件,所以我这里主要是针对ActiveMq的一些配置,包括JmsMessagingTemplateJmsMessageServiceConnectionFactory

这里还通过@Value注解注入了mq的地址,这个地址需要在starter的使用项目中注入,后面我们会演示。

@EnableJms注解的作用是启用消息组件,如果没有这个注解,整个消息组件就没啥用了;

@ConditionalOnClass注解的作用是,只有在至指定的class(这里的JmsMessageServiceImpl.class)存在的时候(也就是依赖了这个类对应的包),配置才会生效(这样看我这里的这个配置没啥用),类似的配置还有好几个,后面研究下;

@ConditionalOnMissingBean注解起的是标记作用,通常和@Bean一起使用,如果加了这个注解,这个类就不允许重复注入了。

业务实现

这里的业务实现就是普通的java实现,前面我们已经在配置类中以及注入过这个类的实例了,后面在引用当前starterspring-boot项目中就可以直接通过@AutoWired注解使用了

public class JmsMessageServiceImpl implements JmsMessageService {
    private final Logger logger = LoggerFactory.getLogger(JmsMessageServiceImpl.class);

    private JmsMessagingTemplate jmsTemplate;

    public JmsMessageServiceImpl(JmsMessagingTemplate jmsTemplate) {
        this.jmsTemplate = jmsTemplate;
    }



    @Override
    public void sendMessage(String mqQueueName, String message) {
        logger.info("method: [sendMessage] input parameter: mqQueueName = {}, message = {}", mqQueueName, message);
        jmsTemplate.convertAndSend(mqQueueName, message);
    }

    @Override
    public MessageReceiveVO sendAndReceive(String mqQueueName, String message) {
        logger.info("method: [sendMessage] input parameter: mqQueueName = {}, message = {}", mqQueueName, message);
        Message<?> messageBack = jmsTemplate.sendAndReceive(mqQueueName, new StringMessage(message));
        String payload = (String) messageBack.getPayload();
        logger.info("method: [sendMessage] return result: payload = {}", payload);
        return JSON.parseObject(payload, MessageReceiveVO.class);
    }

    class StringMessage implements Message<String> {

        private String payload;
        private MessageHeaders messageHeaders;

        public StringMessage(String payload) {
            this.payload = payload;
        }

        @Override
        public String getPayload() {
            return this.payload;
        }

        @Override
        public MessageHeaders getHeaders() {
            return this.messageHeaders;
        }
    }
}

META-INF文件编写

这里才是starter组件的重中之重,如果没有这里的配置文件,你的组件并不会被spring-boot发现。

我们创建一个名字叫spring.factories的文件,然后在文件中添加如下内容:

#-------starter自动装配---------
org.springframework.boot.autoconfigure.EnableAutoConfiguration=io.github.syske.starter.demo.config.AutoConfigurationClass

这里文件名字是固定的,其他名称是无法识别的,文件中的org.springframework.boot.autoconfigure.EnableAutoConfiguration也是固定的,就是一个键名,后面的io.github.syske.starter.demo.config.AutoConfigurationClass是我们配置类的名称,根据spring-boot使用经验,这个配置应该是支持多个类的,用逗号分隔应该就好了,我还没来得及试验,有兴趣的小伙伴自己尝试下。

然后到这里我们的starter就编写完成了,下面我们要打包,然后测试。

spring-boot-starter打包安装

这里打包也很简单,我们直接使用maveninstall工具就可以,需要注意的是,我们要在pom.xml中指定打包类型:

点击install菜单后,我们的start会被安装到本地maven仓库中

测试

因为stater是要引入spring-boot项目中才能使用的,所以我们要先创建一个spring-boot项目,然后引入我们刚才打的starter

这里我们还要在配置文件中添加mq的地址:

然后我们直接在单元测试中测试下我们的stater:

@SpringBootTest
class SpringBootSraterTestApplicationTests {

    @Autowired
    private JmsMessageService jmsMessageService;

    @Test
    void contextLoads() {
        jmsMessageService.sendMessage("spring_boot_starter", "hello spring-boot-start");
    }

}

直接运行这个方法,然后我们登录mq的管理台看下:

可以看到我们的消息已经成功发送到mq中了,说明我们的starter组件已经运行成功了。

总结

spring-boot-starter确实用起来很方便,感觉就像一个插座一样,随插即用,可以说通过spring-boot-starter我们可以真正做到组件化的模块编程,而且在我们的演示项目中,如果我们mq的地址也是固定的话,那我们甚至连配置文件都不需要了,只需要引入starter依赖即可使用其中的spring-boot组件,简直不要太方便。

好了,手写starter就到这里吧,踩坑过程确实比较费时间,所以今天也就更的有点晚了,不过还好,总算完了😂

昨天忘记留项目地址了,下面是本次完整项目的地址,各位小伙伴感兴趣的话,可以去看下:

# starter项目地址
https://github.com/Syske/learning-dome-code/tree/dev/springboot-starter-demo
# 测试项目地址
https://github.com/Syske/learning-dome-code/tree/dev/spring-boot-srater-test

有问题 可以给我留言

posted @ 2021-07-19 08:15  云中志  阅读(152)  评论(0编辑  收藏  举报