1. 程式人生 > >[Spring] SpringBoot 整合 Reactor 事件處理框架

[Spring] SpringBoot 整合 Reactor 事件處理框架

一、 Reactor 框架簡介

          Reactor 是 Spring 社群釋出的基於事件驅動的非同步框架,不僅解耦了程式之間的強呼叫關係,而且有效提升了系統的多執行緒併發處理能力。

          基於 SpringBoot 環境使用 Reactor 框架十分方便,下面作簡要介紹:

二、 Reactor 基本用法

2.1  專案基於 SpringBoot + Maven,建立 SpringBoot maven 專案後,增加 Reactor Pom 依賴,主要是 reactor-bus:

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-bus</artifactId>
        </dependency>
    </dependencies>

2.2   例項化 EventBus Bean,這裡採用內部 Bean 方式實現,其他方式也可以,保證能夠供其它類注入即可

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import reactor.Environment;
import reactor.bus.EventBus;

@Component
public class MyBeans {

    @Bean
    Environment env() {
        return Environment.initializeIfEmpty()
                .assignErrorJournal();
    }

    @Bean
    EventBus createEventBus(Environment env) {
        return EventBus.create(env, Environment.THREAD_POOL);
    }
}

2.3  編寫事件處理程式,需要實現 Consumer<Event<T>> 介面,其中 T 是處理程式接收的資料型別,要根據具體業務設定,這裡使用 Integer

import org.springframework.stereotype.Service;
import reactor.bus.Event;
import reactor.fn.Consumer;

@Service
class Receiver implements Consumer<Event<Integer>> {

    @Override
    public void accept(Event<Integer> ev) {
        System.out.println("Process number " + ev.getData());
    }

}

2.4  關聯事件型別與事件處理程式,通過事件標籤進行繫結,藉助實現 SpringBoot CommandLineRunner 介面,實現啟動自動繫結

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import reactor.bus.EventBus;

import static reactor.bus.selector.Selectors.$;

@Component
@Order(value = 1)
public class ReactorLauncher implements CommandLineRunner {

    @Autowired
    private EventBus eventBus;

    @Autowired
    private Receiver receiver;

    @Override
    public void run(String... args) throws Exception {
        eventBus.on($("number"), receiver);
    }
}

eventBus.on($("number"), receiver); // number型別的事件交給 receiver 處理

2.5  編寫事件傳送程式,傳送程式傳送事件時需要指定標籤,用以區分不同事件,以便交給不同的處理程式處理

import org.springframework.beans.factory.annotation.Autowired;
import reactor.bus.Event;
import reactor.bus.EventBus;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class Publisher {

    @Autowired
    EventBus eventBus;

    @RequestMapping("reactor/demo")
    @ResponseBody
    public void publish() throws InterruptedException {

        for (int i = 0; i < 10; i++) {
            eventBus.notify("number", Event.wrap(i));
        }
    }

}
eventBus.notify("number", Event.wrap(i)); // 傳送number型別事件,將整數 i 作為資料傳遞給事件處理程式 Receiver

三、 總結

整體來看,使用 Spring Reactor 框架還是比較簡單的,只需3步:
1、實現1個事件處理程式
2、繫結事件型別和事件處理程式
3、在需要的地方傳送事件