偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

手把手教你寫(xiě)Spring Boot Starter

開(kāi)發(fā) 前端
如果你看過(guò) spring-kafka 的源代碼,那么你會(huì)發(fā)現(xiàn)所有代碼基本都是仿造其實(shí)現(xiàn)。一方面能夠閱讀 kafka client 在 spring 具體如何實(shí)現(xiàn);同時(shí)通過(guò)編寫(xiě)自己的 spring starter 模塊,學(xué)習(xí) 整個(gè) starter 的實(shí)現(xiàn)過(guò)程。

哈嘍,大家好,我是了不起。

之前寫(xiě)過(guò)關(guān)于 Apache Pulsar 的簡(jiǎn)單示例,用來(lái)了解如何使用 Pulsar 這個(gè)新生代的消息隊(duì)列中間件,但是如果想要在項(xiàng)目中使用,還會(huì)欠缺很多,最明顯的就是 集成復(fù)雜,如果你用過(guò)其他消息中間件,比如 Kafka、RabbitMq,只需要簡(jiǎn)單的引入 jar,就可以通過(guò)注解+配置快速集成到項(xiàng)目中。

開(kāi)始一個(gè) Pulsar Starter

既然已經(jīng)了解了 Apache Pulsar,又認(rèn)識(shí)了 spring-boot-starter,今天不妨來(lái)看下如何寫(xiě)一個(gè) pulsar-spring-boot-starter 模塊。

目標(biāo)

寫(xiě)一個(gè)完整的類似 kafka-spring-boot-starter(springboot 項(xiàng)目已經(jīng)集成到 spring-boot-starter 中),需要考慮到很多 kafka 的特性, 今天我們主要實(shí)現(xiàn)下面幾個(gè)模板

  • 在項(xiàng)目中夠通過(guò)引入 jar 依賴快速集成
  • 提供統(tǒng)一的配置入口
  • 能夠快速發(fā)送消息
  • 能夠基于注解實(shí)現(xiàn)消息的消費(fèi)

定義結(jié)構(gòu)

└── pulsar-starter
├── pulsar-spring-boot-starter
├── pulsar-spring-boot-autoconfigure
├── spring-pulsar
├── spring-pulsar-xx
├── spring-pulsar-sample
└── README.md

整個(gè)模塊的結(jié)構(gòu)如上其中pulsar-starter作為一個(gè)根模塊,主要控制子模塊依賴的其他 jar 的版本以及使用到的插件版本。類似于 Spring-Bom,這樣我們?cè)诤罄m(xù)升級(jí) 時(shí),就可以解決各個(gè)第三方 jar 的可能存在版本沖突導(dǎo)致的問(wèn)題。

  • pulsar-spring-boot-starter

該模塊作為外部項(xiàng)目集成的直接引用 jar,可以認(rèn)為是 pulsar-spring-boot-starter 組件的入口,里面不需要寫(xiě)任何代碼,只需要引入需要的依賴(也就是下面的子模塊)即可

  • pulsar-spring-boot-autoconfigure

該模塊主要定義了 spring.factories 以及 AutoConfigure、Properties。也就是自動(dòng)配置的核心(配置項(xiàng)+Bean 配置)

  • spring-pulsar

該模塊是核心模塊,主要的實(shí)現(xiàn)都在這里

  • spring-pulsar-xx

擴(kuò)展模塊,可以對(duì) spring-pulsar 做更細(xì)化的劃分

  • spring-pulsar-sample

starter 的使用示例項(xiàng)目

實(shí)現(xiàn)

上面我們說(shuō)到實(shí)現(xiàn)目標(biāo),現(xiàn)在看下各個(gè)模塊應(yīng)該包含什么內(nèi)容,以及怎么實(shí)現(xiàn)我們的目標(biāo)

  • 入口 pulsar-spring-boot-starter

上面說(shuō)到 starter 主要是引入整個(gè)模塊基礎(chǔ)的依賴即可,里面不用寫(xiě)代碼。

<dependencies>
<dependency>
<groupId>com.sucl</groupId>
<artifactId>spring-pulsar</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>com.sucl</groupId>
<artifactId>pulsar-spring-boot-autoconfigure</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
  • pulsar-spring-boot-autoconfigure
  1. 添加 spring-boot 基礎(chǔ)的配置
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
  1. 定義自動(dòng)配置類PulsarAutoConfiguration:
  • 引入Properties,基于EnableConfigurationProperties與spring-boot-configuration-processor解析 Properties 生成對(duì)應(yīng)spring-configuration-metadata.json文件,這樣編寫(xiě) application.yml 配置時(shí)就可以自動(dòng)提示配置項(xiàng)的屬性和值了。
  • 構(gòu)建一些必須的 Bean,如 PulsarClient、ConsumerFactory、ConsumerFactory 等
  • Import 配置 PulsarAnnotationDrivenConfiguration,這個(gè)主要是一些額外的配置,用來(lái)支持后面的功能
@Configuration
@EnableConfigurationProperties({PulsarProperties.class})
@Import({PulsarAnnotationDrivenConfiguration.class})
public class PulsarAutoConfiguration {

private final PulsarProperties properties;

public PulsarAutoConfiguration(PulsarProperties properties) {
this.properties = properties;
}

@Bean(destroyMethod = "close")
public PulsarClient pulsarClient() {
ClientBuilder clientBuilder = new ClientBuilderImpl(properties);
return clientBuilder.build();
}

@Bean
@ConditionalOnMissingBean(ConsumerFactory.class)
public ConsumerFactory pulsarConsumerFactory() {
return new DefaultPulsarConsumerFactory(pulsarClient(), properties.getConsumer().buildProperties());
}

@Bean
@ConditionalOnMissingBean(ProducerFactory.class)
public ProducerFactory pulsarProducerFactory() {
return new DefaultPulsarProducerFactory(pulsarClient(), properties.getProducer().buildProperties());
}

}
  1. 配置 spring.factory

在目錄src/main/resources/META-INF下創(chuàng)建spring.factories,內(nèi)容如下:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.sucl.pulsar.autoconfigure.PulsarAutoConfiguration
  • spring-pulsar
  1. 添加 pulsar-client 相關(guān)的依賴
<dependencies>
<dependency>
<groupId>org.apache.pulsar</groupId>
<artifactId>pulsar-client</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-messaging</artifactId>
</dependency>
</dependencies>
  1. 定義 EnablePulsar,之前說(shuō)到過(guò),@Enable 注解主要是配合 AutoConfigure 來(lái)做功能加強(qiáng),沒(méi)有了自動(dòng)配置,我們依然可以使用這些模塊的功能。這里做了一件事,向 Spring 容器注冊(cè)了兩個(gè) Bean
  • PulsarListenerAnnotationBeanProcessor 在 Spring Bean 生命周期中解析注解自定義注解 PulsarListener、PulsarHandler,
  • PulsarListenerEndpointRegistry 用來(lái)構(gòu)建 Consumer 執(zhí)行環(huán)境以及對(duì) TOPIC 的監(jiān)聽(tīng)、觸發(fā)消費(fèi)回調(diào)等等,可以說(shuō)是最核心的 Bean
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({PulsarListenerConfigurationSelector.class})
public @interface EnablePulsar {

}
  1. 定義注解,參考 RabbitMq,主要針對(duì)需要關(guān)注的類與方法,分別對(duì)應(yīng)注解@PulsarListener、@PulsarHandler,通過(guò)這兩個(gè)注解配合可以讓我們監(jiān)聽(tīng)到關(guān)注的 TOPIC, 當(dāng)有消息產(chǎn)生時(shí),觸發(fā)對(duì)應(yīng)的方法進(jìn)行消費(fèi)。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PulsarListener {

/**
*
* @return TOPIC 支持SPEL
*/
String[] topics() default {};

/**
*
* @return TAGS 支持SPEL
*/
String[] tags() default {};
}

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface PulsarHandler {

}
  1. 注解@PulsarListener 的處理流程比較復(fù)雜,這里用一張圖描述,或者可以通過(guò)下面 github 的源代碼查看具體實(shí)現(xiàn)

圖片

flow

  • spring-pulsar-sample

按照下面的流程,你會(huì)發(fā)現(xiàn)通過(guò)簡(jiǎn)單的幾行代碼就能夠?qū)崿F(xiàn)消息的生產(chǎn)與消費(fèi),并集成到項(xiàng)目中去。

  1. 簡(jiǎn)單寫(xiě)一個(gè) SpringBoot 項(xiàng)目,并添加 pulsar-spring-boot-starter
<dependencies>
<dependency>
<groupId>com.sucl</groupId>
<artifactId>pulsar-spring-boot-starter</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>

2.添加配置

cycads:
pulsar:
service-url: pulsar://localhost:6650
listener-topics: TOPIC_TEST

3.編寫(xiě)對(duì)應(yīng)消費(fèi)代碼

@Slf4j
@Component
@PulsarListener(topics = "#{'${cycads.listener-topics}'.split(',')}")
public class PulsarDemoListener {

@PulsarHandler
public void onConsumer(Message message){
log.info(">>> 接收到消息:{}", message.getPayload());
}

}
  1. 向 Pulsar Broker 發(fā)送消息進(jìn)行測(cè)試
@Slf4j
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {ContextConfig.class})
@Import({PulsarAutoConfiguration.class})
public class ProducerTests {

@Autowired
private ProducerFactory producerFactory;

@Test
public void sendMessage() {
Producer producer = producerFactory.createProducer("TOPIC_TEST");
MessageId messageId = producer.send("this is a test message");
log.info(">>>>>>> 消息發(fā)送完成:{}", messageId);
}

@Configuration
@PropertySource(value = "classpath:application-test.properties")
static class ContextConfig {
//
}
}
  1. 控制臺(tái)可以看到這樣的結(jié)果

2023-02-26 19:57:15.572  INFO 26520 --- [pulsar-01] c.s.p.s.listener.PulsarDemoListener : >>> 接收到消息:GenericMessage [payload=this is a test message, headers={id=f861488c-2afb-b2e7-21a1-f15e9759eec5, timestamp=1677412635571}]

知識(shí)點(diǎn)

  • Pulsar Client

基于 pulsar-client 提供的 ConfigurationData 擴(kuò)展 Properties;了解 Pulsar Client 如何連接 Broker 并進(jìn)行消息消費(fèi),包括同步消費(fèi)、異步消費(fèi)等等

  • spring.factories

實(shí)現(xiàn) starter 自動(dòng)配置的關(guān)鍵,基于 SPI 完成配置的自動(dòng)加載

  • Spring Bean 生命周期

通過(guò) Bean 生命周期相關(guān)擴(kuò)展實(shí)現(xiàn)注解的解析與容器的啟動(dòng),比如 BeanPostProcessor, BeanFactoryAware, SmartInitializingSingleton, InitializingBean, DisposableBean 等

  • Spring Messaging

基于回調(diào)與 MethodHandler 實(shí)現(xiàn)消息體的封裝、參數(shù)解析以及方法調(diào)用;

源碼示例

??https://github.com/sucls/pulsar-starter.git??

結(jié)束語(yǔ)

如果你看過(guò) spring-kafka 的源代碼,那么你會(huì)發(fā)現(xiàn)所有代碼基本都是仿造其實(shí)現(xiàn)。一方面能夠閱讀 kafka client 在 spring 具體如何實(shí)現(xiàn);同時(shí)通過(guò)編寫(xiě)自己的 spring starter 模塊,學(xué)習(xí) 整個(gè) starter 的實(shí)現(xiàn)過(guò)程。

責(zé)任編輯:武曉燕 來(lái)源: Java技術(shù)指北
相關(guān)推薦

2019-11-12 10:50:13

Spring BootstarterJava

2021-06-29 12:27:19

Spring BootCAS 登錄

2025-02-19 08:00:00

SpringBootOllamaDeepSeek

2021-07-14 09:00:00

JavaFX開(kāi)發(fā)應(yīng)用

2025-05-07 00:31:30

2011-01-10 14:41:26

2011-05-03 15:59:00

黑盒打印機(jī)

2018-05-16 13:50:30

Python網(wǎng)絡(luò)爬蟲(chóng)Scrapy

2018-05-16 15:46:06

Python網(wǎng)絡(luò)爬蟲(chóng)PhantomJS

2022-01-08 20:04:20

攔截系統(tǒng)調(diào)用

2023-04-26 12:46:43

DockerSpringKubernetes

2022-03-14 14:47:21

HarmonyOS操作系統(tǒng)鴻蒙

2022-12-07 08:42:35

2022-07-27 08:16:22

搜索引擎Lucene

2021-02-26 11:54:38

MyBatis 插件接口

2011-02-22 13:46:27

微軟SQL.NET

2021-12-28 08:38:26

Linux 中斷喚醒系統(tǒng)Linux 系統(tǒng)

2022-03-08 11:17:54

函數(shù)指針回調(diào)函數(shù)C語(yǔ)言

2022-08-11 07:32:51

Starter自動(dòng)裝配

2021-06-22 10:43:03

Webpack loader plugin
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)