1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        編寫你的第一個(gè)spring-boot-starter

        共 7341字,需瀏覽 15分鐘

         ·

        2021-07-22 08:32


        前言

        我們?cè)谑褂?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);">spring-boot的時(shí)候,會(huì)經(jīng)常用到各種各樣的starter,比如spring-boot-starter-web,不知道各個(gè)小伙伴有沒(méi)有好奇過(guò)這些starter到底是怎么定義出來(lái)的,反正我好奇過(guò),但是一直沒(méi)有去深入了解過(guò),最近在項(xiàng)目開(kāi)發(fā)中,我們需要封裝一個(gè)mq的通用組件,有個(gè)同事就封裝成一個(gè)starter,然后就勾起了學(xué)習(xí)和研究的好奇心,所以想著趁今天的時(shí)間做一個(gè)小demo,寫一個(gè)屬于自己的starter

        下面我們就來(lái)看下具體如何實(shí)現(xiàn)。

        手寫spring-boot-starter

        創(chuàng)建項(xiàng)目

        首先我們要?jiǎng)?chuàng)建一個(gè)maven項(xiàng)目,根據(jù)自己的需要引入項(xiàng)目依賴,因?yàn)槲覀円獙懙氖?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);">sprin-boot的starter,所以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>

        因?yàn)?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);">starter的核心其實(shí)是配置類,而這些配置類注解都在spring-boot-starter包下。創(chuàng)建完成后的項(xiàng)目結(jié)構(gòu)如下:

        我的這個(gè)組件是一個(gè)通用的消息發(fā)送組件,所以我還引入activemq的相關(guān)包,對(duì)demo感興趣的小伙伴可以直接去看項(xiàng)目源碼,文末有地址。

        配置類

        這里就是starter的核心了,這里我們要對(duì)組件進(jìn)行配置,主要是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);
            }
        }

        前面說(shuō)了我的組件是通用的消息組件,所以我這里主要是針對(duì)ActiveMq的一些配置,包括JmsMessagingTemplate、JmsMessageServiceConnectionFactory。

        這里還通過(guò)@Value注解注入了mq的地址,這個(gè)地址需要在starter的使用項(xiàng)目中注入,后面我們會(huì)演示。

        @EnableJms注解的作用是啟用消息組件,如果沒(méi)有這個(gè)注解,整個(gè)消息組件就沒(méi)啥用了;

        @ConditionalOnClass注解的作用是,只有在至指定的class(這里的JmsMessageServiceImpl.class)存在的時(shí)候(也就是依賴了這個(gè)類對(duì)應(yīng)的包),配置才會(huì)生效(這樣看我這里的這個(gè)配置沒(méi)啥用),類似的配置還有好幾個(gè),后面研究下;

        @ConditionalOnMissingBean注解起的是標(biāo)記作用,通常和@Bean一起使用,如果加了這個(gè)注解,這個(gè)類就不允許重復(fù)注入了。

        業(yè)務(wù)實(shí)現(xiàn)

        這里的業(yè)務(wù)實(shí)現(xiàn)就是普通的java實(shí)現(xiàn),前面我們已經(jīng)在配置類中以及注入過(guò)這個(gè)類的實(shí)例了,后面在引用當(dāng)前starterspring-boot項(xiàng)目中就可以直接通過(guò)@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組件的重中之重,如果沒(méi)有這里的配置文件,你的組件并不會(huì)被spring-boot發(fā)現(xiàn)。

        我們創(chuàng)建一個(gè)名字叫spring.factories的文件,然后在文件中添加如下內(nèi)容:

        #-------starter自動(dòng)裝配---------
        org.springframework.boot.autoconfigure.EnableAutoConfiguration=io.github.syske.starter.demo.config.AutoConfigurationClass

        這里文件名字是固定的,其他名稱是無(wú)法識(shí)別的,文件中的org.springframework.boot.autoconfigure.EnableAutoConfiguration也是固定的,就是一個(gè)鍵名,后面的io.github.syske.starter.demo.config.AutoConfigurationClass是我們配置類的名稱,根據(jù)spring-boot使用經(jīng)驗(yàn),這個(gè)配置應(yīng)該是支持多個(gè)類的,用逗號(hào)分隔應(yīng)該就好了,我還沒(méi)來(lái)得及試驗(yàn),有興趣的小伙伴自己嘗試下。

        然后到這里我們的starter就編寫完成了,下面我們要打包,然后測(cè)試。

        spring-boot-starter打包安裝

        這里打包也很簡(jiǎn)單,我們直接使用maveninstall工具就可以,需要注意的是,我們要在pom.xml中指定打包類型:

        點(diǎn)擊install菜單后,我們的start會(huì)被安裝到本地maven倉(cāng)庫(kù)中

        測(cè)試

        因?yàn)?code style="overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;color: rgb(255, 100, 65);">stater是要引入spring-boot項(xiàng)目中才能使用的,所以我們要先創(chuàng)建一個(gè)spring-boot項(xiàng)目,然后引入我們剛才打的starter

        這里我們還要在配置文件中添加mq的地址:

        然后我們直接在單元測(cè)試中測(cè)試下我們的stater:

        @SpringBootTest
        class SpringBootSraterTestApplicationTests {

            @Autowired
            private JmsMessageService jmsMessageService;

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

        }

        直接運(yùn)行這個(gè)方法,然后我們登錄mq的管理臺(tái)看下:

        可以看到我們的消息已經(jīng)成功發(fā)送到mq中了,說(shuō)明我們的starter組件已經(jīng)運(yùn)行成功了。

        總結(jié)

        spring-boot-starter確實(shí)用起來(lái)很方便,感覺(jué)就像一個(gè)插座一樣,隨插即用,可以說(shuō)通過(guò)spring-boot-starter我們可以真正做到組件化的模塊編程,而且在我們的演示項(xiàng)目中,如果我們mq的地址也是固定的話,那我們甚至連配置文件都不需要了,只需要引入starter依賴即可使用其中的spring-boot組件,簡(jiǎn)直不要太方便。

        好了,手寫starter就到這里吧,踩坑過(guò)程確實(shí)比較費(fèi)時(shí)間,所以今天也就更的有點(diǎn)晚了,不過(guò)還好,總算完了??

        - END -


        瀏覽 53
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产区精品豆花 | 青娱乐在线播放视频 | 欧美精品特一级黑妇黄色影院 | 91你懂得 | 韩国三级丰满少妇高潮 | 亚洲女同女同志6969 | 欧美AAA黄片 | 免费看操逼视频网站 | 我要看国产一级片 | 美女裸体被c视频 |