【spring指南系列】使用Redis進行消息傳遞

本指南將指導您完成使用Spring Data Redis發布和訂閱(通過Redis發送)的消息的過程。

What you』ll build

你將構建一個使用StringRedisTemplate來發布一個字元串消息的應用程序,並且有一個POJO使用MessageListenerAdapter來訂閱。

**使用Spring Data Redis作為發布消息的手段可能聽起來很奇怪,但是你會發現,Redis不僅提供了NoSQL數據存儲,還提供了一個消息系統.

What you』ll need

  • 約15分鐘

  • 最喜歡的文本編輯器或IDE

  • JDK 1.8或更高版本

  • Gradle 2.3+或Maven 3.0+

  • 您也可以從本指南導入代碼,以及直接在Spring Tool Suite(STS)中查看網頁,並從那 里開始工作 。

  • Redis伺服器(安裝說明如下)

How to complete this guide

與大多數[Spring 入門指南]一樣(Spring Guides),您可以從頭開始並完成每個步驟,也可以繞過已經熟悉的基本設置步驟。 無論如何,你最終得到工作代碼。

  • Download 並解壓縮本指南的源代碼倉庫,或使用 Git: git clone spring-guides/gs-messaging-redis

  • cd 到 gs-messaging-redis/initial

  • 跳轉到Create a Redis message receiver.

當你做完這一切, 你可以根據 gs-messaging-redis/complete中的代碼檢查結果.

Build with Gradle

首先你設置一個基本的構建腳本。 你可以使用任何你喜歡的一個來構建項目,當使用Spring構建應用程序時,但是需要使用Gradle和Maven 來寫你的代碼。 如果你不熟悉任何一個,請參考使用Gradle構建Java項目或使用Maven構建Java項目。

Create the directory structure

在您選擇的項目目錄中,創建以下子目錄結構; 例如,在* nix*系統上使用`mkdir -p src / main / java / hello:

└── srcn └── mainn └── javan └── hellon

Create a Gradle build file

下面是 initial Gradle build file.build.gradle

buildscript {n repositories {n mavenCentral()n }n dependencies {n classpath("org.springframework.boot:spring-boot-gradle-plugin:1.4.3.RELEASE")n }n}nnapply plugin: javanapply plugin: eclipsenapply plugin: ideanapply plugin: org.springframework.bootnnjar {n baseName = gs-messaging-redisn version = 0.1.0n}nnrepositories {n mavenCentral()n}nnsourceCompatibility = 1.8ntargetCompatibility = 1.8nndependencies {n compile("org.springframework.boot:spring-boot-starter")n compile("org.springframework.boot:spring-boot-starter-redis")n testCompile("junit:junit")n}n

Spring Boot gradle插件提供了許多方便的功能:

  • 它收集類路徑上的所有jar,並構建一個單獨的,可運行的「über-jar」,這使得執行和傳遞服務更加方便。

  • 它搜索public static void main()方法來標記為可運行類。

  • 它提供了一個內置的依賴解析器,設置版本號匹配Spring Boot dependencies. 你可以覆蓋任何你想要的版本,但它會默認為Boot的選擇的版本集。

Build with Maven

首先你設置一個基本的構建腳本。 你可以使用任何你喜歡的一個來構建項目,當使用Spring構建應用程序,但是需要使用Maven來構建你的代碼。 如果你不熟悉Maven,請參考使用Maven構建Java項目.

Create the directory structure

在您選擇的項目目錄中,創建以下子目錄結構; 例如,在* nix*系統上使用`mkdir -p src / main / java / hello:

└── srcn └── mainn └── javan └── hellon

pom.xml

<?xml version="1.0" encoding="UTF-8"?>n<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"n xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">n <modelVersion>4.0.0</modelVersion>nn <groupId>org.springframework</groupId>n <artifactId>gs-messaging-redis</artifactId>n <version>0.1.0</version>nn <parent>n <groupId>org.springframework.boot</groupId>n <artifactId>spring-boot-starter-parent</artifactId>n <version>1.4.3.RELEASE</version>n </parent>nn <properties>n <java.version>1.8</java.version>n </properties>nn <dependencies>n <dependency>n <groupId>org.springframework.boot</groupId>n <artifactId>spring-boot-starter</artifactId>n </dependency>n <dependency>n <groupId>org.springframework.boot</groupId>n <artifactId>spring-boot-starter-redis</artifactId>n </dependency>n </dependencies>nnn <build>n <plugins>n <plugin>n <groupId>org.springframework.boot</groupId>n <artifactId>spring-boot-maven-plugin</artifactId>n </plugin>n </plugins>n </build>nn <repositories>n <repository>n <id>spring-releases</id>n <name>Spring Releases</name>n <url>https://repo.spring.io/libs-release</url>n </repository>n </repositories>n <pluginRepositories>n <pluginRepository>n <id>spring-releases</id>n <name>Spring Releases</name>n <url>https://repo.spring.io/libs-release</url>n </pluginRepository>n </pluginRepositories>n</project>n

Spring Boot Maven插件 提供了許多方便的功能:

  • 它收集類路徑上的所有jar,並構建一個單獨的,可運行的「über-jar」,這使得執行和運輸服務更加方便。

  • 它搜索public static void main()方法來標記為可運行類。

  • 它提供了一個內置的依賴解析器,設置版本號匹配Spring Boot dependencies. 你可以覆蓋任何你想要的版本,但它會默認為Boot的選擇的版本集。

Build with your IDE

  • 閱讀如何通過本指南直接導入Spring Tool Suite。

  • 閱讀如何在IntelliJ IDEA上使用本指南。

Standing up a Redis server

在您可以構建消息傳遞應用程序之前,您需要設置將要處理接收和發送消息的伺服器。

Redis是一個開源的,BSD許可的鍵值數據存儲,它還帶有一個消息系統。 伺服器在Redis 上免費提供。 你可以手動下載,或者如果你使用Mac的homebrew:

brew install redisn

解壓縮Redis後,您可以使用默認設置啟動它。

redis-servern

您應該看到這樣的消息:

[35142] 01 May 14:36:28.939 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.confn[35142] 01 May 14:36:28.940 * Max number of open files set to 10032n _._n _.-``__ -._n _.-`` `. `_. -._ Redis 2.6.12 (00000000/0) 64 bitn .-`` .-```. ```/ _.,_ -._n ( , .-` | `, ) Running in stand alone moden |`-._`-...-` __...-.``-._|` _.-| Port: 6379n | `-._ `._ / _.- | PID: 35142n `-._ `-._ `-./ _.- _.-n |`-._`-._ `-.__.- _.-_.-|n | `-._`-._ _.-_.- | http://redis.ion `-._ `-._`-.__.-_.- _.-n |`-._`-._ `-.__.- _.-_.-|n | `-._`-._ _.-_.- |n `-._ `-._`-.__.-_.- _.-n `-._ `-.__.- _.-n `-._ _.-n `-.__.-nn[35142] 01 May 14:36:28.941 # Server started, Redis version 2.6.12n[35142] 01 May 14:36:28.941 * The server is now ready to accept connections on port 6379n

Create a Redis message receiver

在任何基於消息的應用程序中,有消息發布者和消息接收者。 要創建消息接收器,請使用響應消息的方法實現一個接收器:src/main/java/hello/Receiver.java

package hello;nnimport java.util.concurrent.CountDownLatch;nnimport org.slf4j.Logger;nimport org.slf4j.LoggerFactory;nimport org.springframework.beans.factory.annotation.Autowired;nnpublic class Receiver {n private static final Logger LOGGER = LoggerFactory.getLogger(Receiver.class);nn private CountDownLatch latch;nn @Autowiredn public Receiver(CountDownLatch latch) {n this.latch = latch;n }nn public void receiveMessage(String message) {n LOGGER.info("Received <" + message + ">");n latch.countDown();n }n}n

Receiver是一個簡單的POJO,它定義了一個接收消息的方法。 正如你在註冊Receiver作為消息偵聽器時所看到的,你可以將消息處理方法命名為任何你想要的。

**為了演示的目的,它由具有倒計時鎖存器(CountDownLatch,這個不清楚的可以谷歌一下,並發編程經常用的東西)的構造函數自動裝配。 這樣,它可以在它接收到消息時發出信號.

Register the listener and send a message

Spring Data Redis提供了使用Redis發送和接收消息所需的所有組件。 具體來說,你需要配置:

  • 連接工廠(connection factory)

  • 消息偵聽器容器( message listener container)

  • Redis模板(Redis template)

你將使用Redis模板發送消息,使用消息偵聽器容器註冊「Receiver」,以便它將接收消息。 連接工廠驅動模板和消息偵聽器容器,使它們能夠連接到Redis伺服器。

這個例子使用Spring Boot的默認RedisConnectionFactory,一個JedisConnectionFactory的實例,它基於Jedis Redis庫。 連接工廠被注入到消息偵聽器容器和Redis模板中。

src/main/java/hello/Application.java

package hello;nnimport java.util.concurrent.CountDownLatch;nnimport org.slf4j.Logger;nimport org.slf4j.LoggerFactory;nimport org.springframework.boot.SpringApplication;nimport org.springframework.boot.autoconfigure.SpringBootApplication;nimport org.springframework.context.ApplicationContext;nimport org.springframework.context.annotation.Bean;nimport org.springframework.data.redis.connection.RedisConnectionFactory;nimport org.springframework.data.redis.core.StringRedisTemplate;nimport org.springframework.data.redis.listener.PatternTopic;nimport org.springframework.data.redis.listener.RedisMessageListenerContainer;nimport org.springframework.data.redis.listener.adapter.MessageListenerAdapter;nn@SpringBootApplicationnpublic class Application {nntprivate static final Logger LOGGER = LoggerFactory.getLogger(Application.class);nnt@BeanntRedisMessageListenerContainer container(RedisConnectionFactory connectionFactory,ntttMessageListenerAdapter listenerAdapter) {nnttRedisMessageListenerContainer container = new RedisMessageListenerContainer();nttcontainer.setConnectionFactory(connectionFactory);nttcontainer.addMessageListener(listenerAdapter, new PatternTopic("chat"));nnttreturn container;nt}nnt@BeanntMessageListenerAdapter listenerAdapter(Receiver receiver) {nttreturn new MessageListenerAdapter(receiver, "receiveMessage");nt}nnt@BeanntReceiver receiver(CountDownLatch latch) {nttreturn new Receiver(latch);nt}nnt@BeanntCountDownLatch latch() {nttreturn new CountDownLatch(1);nt}nnt@BeanntStringRedisTemplate template(RedisConnectionFactory connectionFactory) {nttreturn new StringRedisTemplate(connectionFactory);nt}nntpublic static void main(String[] args) throws InterruptedException {nnttApplicationContext ctx = SpringApplication.run(Application.class, args);nnttStringRedisTemplate template = ctx.getBean(StringRedisTemplate.class);nttCountDownLatch latch = ctx.getBean(CountDownLatch.class);nnttLOGGER.info("Sending message...");ntttemplate.convertAndSend("chat", "Hello from Redis!");nnttlatch.await();nnttSystem.exit(0);nt}n}n

在listenerAdapter方法中定義的bean作為參數,並在container中定義的消息偵聽器容器中註冊為消息偵聽器,並將在「chat」主題上偵聽消息。因為Receiver類是一個POJO,它需要被包裝在一個消息監聽器適配器中,該適配器實現addMessageListener()所需的MessageListener介面。消息偵聽器適配器還配置為在消息到達時調用Receiver上的receiveMessage()`方法。

連接工廠和消息監聽器容器bean都是你用來監聽消息的。要發送消息,您還需要一個Redis模板。這裡,它是一個配置為StringRedisTemplate的bean,是RedisTemplate的一個實現,它專註於Redis的常見用法,其中鍵和值都是String。

main()方法通過創建一個Spring應用程序上下文來處理所有事情。應用程序上下文然後啟動消息偵聽器容器,消息偵聽器容器bean開始偵聽消息。 main()方法然後從應用程序上下文中檢索StringRedisTemplate bean(其實就是IOC里的DL),並使用它在 "chat"主題下發送「Hello from Redis!」消息。最後,它關閉Spring應用程序上下文,應用程序結束。

Build an executable JAR

您可以使用Gradle或Maven從命令行運行應用程序。 或者,您可以構建單個可執行文件,其中包含所有必需的依賴關係,類和資源,並運行它。 這使得在整個開發生命周期中,易於跨不同環境將服務作為應用程序進行發布,維護版本和部署等等。

如果您使用Gradle,可以使用./gradlew bootRun運行應用程序。 或者你可以使用./gradlew build來構建JAR文件。 然後可以運行JAR文件:

java -jar build/libs/gs-messaging-redis-0.1.0.jarn

如果您使用Maven,可以使用./mvnw spring-boot:run運行應用程序。 或者你可以用./mvnw clean package構建JAR文件。 然後可以運行JAR文件:

java -jar target/gs-messaging-redis-0.1.0.jarn

**上面的過程將創建一個可運行的JAR。 您也可以選擇build a classic WAR file

您應該看到類似下面的輸出:

. ____ _ __ _ _n / / ____ __ _ _(_)_ __ __ _ n( ( )___ | _ | _| | _ / _` | n / ___)| |_)| | | | | || (_| | ) ) ) )n |____| .__|_| |_|_| |___, | / / / /n =========|_|==============|___/=/_/_/_/n :: Spring Boot :: (v1.4.3.RELEASE)nn2014-04-18 08:03:34.032 INFO 47002 --- [ main] hello.Application : Starting Application on retina with PID 47002 (/Users/gturnquist/src/spring-guides/gs-messaging-redis/complete/target/classes started by gturnquist)n2014-04-18 08:03:34.062 INFO 47002 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a53c84a: startup date [Fri Apr 18 08:03:34 CDT 2014]; root of context hierarchyn2014-04-18 08:03:34.326 INFO 47002 --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase 2147483647n2014-04-18 08:03:34.357 INFO 47002 --- [ main] hello.Application : Started Application in 0.605 seconds (JVM running for 0.899)n2014-04-18 08:03:34.357 INFO 47002 --- [ main] hello.Application : Sending message...n2014-04-18 08:03:34.370 INFO 47002 --- [ container-2] hello.Receiver : Received <Hello from Redis!>n2014-04-18 08:03:34.379 INFO 47002 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@7a53c84a: startup date [Fri Apr 18 08:03:34 CDT 2014]; root of context hierarchyn2014-04-18 08:03:34.380 INFO 47002 --- [ Thread-1] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 2147483647n

最後

恭喜! 你剛剛使用Spring和Redis開發了一個簡單的發布和訂閱應用程序。

系列回顧:

【spring指南系列】計劃任務

【spring指南系列】使用RESTful Web服務

【spring 指南系列】如何更好的設計RESTful API

  • 翻譯自:Messaging with Redis

  • 本人同步博客:一葉知秋

推薦閱讀:

springcloud: 配置中心svn示例和refresh
Spring MVC中使用Thymeleaf模板引擎
史上最簡單的SpringCloud教程 | 第二篇:服務消費者(rest + ribbon)
史上最簡單的 SpringCloud 教程(1) 服務的註冊與發現(Eureka)

TAG:Redis | SpringBoot | Spring |