<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          內(nèi)容回顧 | 編寫你的第一個(gè)spring-boot-starter

          共 7371字,需瀏覽 15分鐘

           ·

          2021-09-06 15:38

          今天偷個(gè)懶,暫時(shí)就不分享新內(nèi)容了,休息一下,明天我們繼續(xù)哈!

          前言

          我們?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è)小伙伴有沒有好奇過這些starter到底是怎么定義出來的,反正我好奇過,但是一直沒有去深入了解過,最近在項(xiàng)目開發(fā)中,我們需要封裝一個(gè)mq的通用組件,有個(gè)同事就封裝成一個(gè)starter,然后就勾起了學(xué)習(xí)和研究的好奇心,所以想著趁今天的時(shí)間做一個(gè)小demo,寫一個(gè)屬于自己的starter。

          下面我們就來看下具體如何實(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);
              }
          }

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

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

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

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

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

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

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

          這里文件名字是固定的,其他名稱是無法識(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)該就好了,我還沒來得及試驗(yàn),有興趣的小伙伴自己嘗試下。

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

          spring-boot-starter打包安裝

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

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

          測(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中了,說明我們的starter組件已經(jīng)運(yùn)行成功了。

          總結(jié)

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

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

          - END -


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

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  另类罕见稀奇videos | 久草热首页 | 性爱激情视频网站 | 国产成人精品电影 | 你懂的网址国产,欧美 |