<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>

          編寫你的第一個spring-boot-starter

          共 7341字,需瀏覽 15分鐘

           ·

          2021-07-22 08:32


          前言

          我們在使用spring-boot的時候,會經(jīng)常用到各種各樣的starter,比如spring-boot-starter-web,不知道各個小伙伴有沒有好奇過這些starter到底是怎么定義出來的,反正我好奇過,但是一直沒有去深入了解過,最近在項目開發(fā)中,我們需要封裝一個mq的通用組件,有個同事就封裝成一個starter,然后就勾起了學(xué)習(xí)和研究的好奇心,所以想著趁今天的時間做一個小demo,寫一個屬于自己的starter

          下面我們就來看下具體如何實現(xiàn)。

          手寫spring-boot-starter

          創(chuàng)建項目

          首先我們要創(chuàng)建一個maven項目,根據(jù)自己的需要引入項目依賴,因為我們要寫的是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包下。創(chuàng)建完成后的項目結(jié)構(gòu)如下:

          我的這個組件是一個通用的消息發(fā)送組件,所以我還引入activemq的相關(guān)包,對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的一些配置,包括JmsMessagingTemplate、JmsMessageServiceConnectionFactory。

          這里還通過@Value注解注入了mq的地址,這個地址需要在starter的使用項目中注入,后面我們會演示。

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

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

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

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

          這里的業(yè)務(wù)實現(xiàn)就是普通的java實現(xiàn),前面我們已經(jīng)在配置類中以及注入過這個類的實例了,后面在引用當(dāng)前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發(fā)現(xiàn)。

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

          #-------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是我們配置類的名稱,根據(jù)spring-boot使用經(jīng)驗,這個配置應(yīng)該是支持多個類的,用逗號分隔應(yīng)該就好了,我還沒來得及試驗,有興趣的小伙伴自己嘗試下。

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

          spring-boot-starter打包安裝

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

          點擊install菜單后,我們的start會被安裝到本地maven倉庫中

          測試

          因為stater是要引入spring-boot項目中才能使用的,所以我們要先創(chuàng)建一個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的管理臺看下:

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

          總結(jié)

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

          好了,手寫starter就到這里吧,踩坑過程確實比較費時間,所以今天也就更的有點晚了,不過還好,總算完了??

          - END -


          瀏覽 53
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <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>
                  国产免费大香蕉 | 国产一级无码Av片在线观看 | 久久国产视频福利 | 国产精品自拍小视频 | 成人免费看片又大又黄 |