javascript
Spring数据和Redis
本文是我們學院課程的一部分,標題為Redis NoSQL鍵值存儲 。
這是Redis的速成班。 您將學習如何安裝Redis并啟動服務器。 此外,您將在Redis命令行中亂七八糟。 接下來是更高級的主題,例如復制,分片和集群,同時還介紹了Redis與Spring Data的集成。 在這里查看 !
目錄
1.簡介 2.先決條件 3.選擇Redis Java客戶端 4. Java應用程序依賴性和Eclipse 5.在Spring數據Redis上配置獨立Redis 6.配置與分片(分區)Redis的連接 7.配置與Redis群集的連接 8.使用Spring Data Redis訪問Redis 9.使用Spring Data Redis進行事務 10.使用Spring Data Redis進行流水線 11.使用Spring Data Redis發布/訂閱 12.結論1.簡介
創建Redis是為了解決實際軟件系統的實際問題。 到目前為止,我們已經探索了非常豐富的Redis功能集,但實際上并沒有在實際的應用程序中使用它們。 為了填補這一空白,本教程的最后一部分專門介紹了此主題。 我們將構建一個使用Redis和出色的Spring Data Redis ( http://projects.spring.io/spring-data-redis/ )項目以及Spring Framework ( http://projects.spring.io )的簡單Java應用程序。 / spring-framework / ),請參閱Spring項目組合( http://spring.io/ )。 撰寫本文時, Spring Data Redis和Spring Framework的最新發布版本分別為1.2.0和4.0.2 。
在深入探討細節之前,值得一提的是,Redis支持各種應用程序框架和編程語言。 客戶端的完整列表可在此處找到: http : //redis.io/clients 。
本教程的其余部分假定讀者能夠使用Java進行編程,并且對Spring Framework ( http://projects.spring.io/spring-framework/ )具有基本的了解。
2.先決條件
Java開發人員的常用工具集包括JDK(Java開發工具包)和類似Eclipse或Intellij IDEA的IDE,以促進應用程序開發過程。 我們將使用的最新JDK版本是1.7_51 ,可以從http://www.oracle.com/technetwork/java/javase/downloads/index.html下載。
IDE的選擇是Eclipse ,它的最新版本是4.3.2 ,可以從https://www.eclipse.org/downloads/下載( 適用于Java開發人員的 Eclipse IDE,適用于Java EE開發人員的Eclipse IDE或Spring Tool Suite版本很好)。
3.選擇Redis Java客戶端
有幾種Java客戶端可用于從Java應用程序訪問Redis( Spring Data Redis也支持下面列出的所有客戶端):
- 杰迪斯: https : //github.com/xetorthio/jedis
- JRedis: https : //github.com/alphazero/jredis
- 生菜: https : //github.com/wg/lettuce
從功能的角度來看,它們都很相似,但是Jedis已獲得越來越多的普及并被廣泛使用。 話雖如此, Jedis也是我們應用程序的選擇。
4. Java應用程序依賴性和Eclipse
我們將要構建的項目將介紹到目前為止已經討論過的所有重要Redis功能,但這些功能來自應用程序開發人員。 我們將從一個基本示例開始,假設有一個獨立的Redis實例并在某個地方運行(讓我們將其稱為redis-host )。 大多數方案將以一個小的JUnit ( http://junit.org/ )測試片段的形式呈現。
Java世界中事實上的構建和依賴性管理工具仍然是Apache Maven ( http://maven.apache.org/ ),我們將使用的版本是3.1.1,可以從http://maven.apache下載。 org / docs / 3.1.1 / release-notes.html 。 實際上,我們不會使用太多的Apache Maven來讓Eclipse代表我們完成這項工作,但是我們將研究基本的依賴項描述文件,該文件通常稱為pom.xml 。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.javacodegeeks</groupId><artifactId>redis</artifactId><version>0.0.1-SNAPSHOT</version><packaging>jar</packaging><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring.version>4.0.2.RELEASE</spring.version></properties><dependencies><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-redis</artifactId><version>1.2.0.RELEASE</version></dependency><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>2.4.1</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>${spring.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring.version}</version></dependency><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.0.13</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-test</artifactId><version>${spring.version}</version><scope>test</scope></dependency><dependency><groupId>org.hamcrest</groupId><artifactId>hamcrest-all</artifactId><version>1.3</version><scope>test</scope></dependency><dependency><groupId>com.jayway.awaitility</groupId><artifactId>awaitility</artifactId><version>1.5.0</version><scope>test</scope></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.11</version><scope>test</scope></dependency></dependencies><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.7</source><target>1.7</target></configuration></plugin></plugins></build> </project>如果您是經驗豐富的Java開發人員,那么pom.xml文件應該非常熟悉。 但是對于新手來說,一些評論可能會有所幫助。 基本上,我們聲明名為com.javacodegeeks.redis的項目取決于:
- 杰迪斯( redis.clients.jedis )
- Spring Data Redis( org.springframework.data.spring-data-redis )
- Spring框架( org.springframework.spring-core , org.springframework.spring-context , org.springframework.spring-tx , org.springframework.spring-test )
- JUnit和隨附的測試腳手架( junit.junit , org.hamcrest.hamcrest-all , com.jayway.awaitility.awaitility )
至此,我們可以使用Existing Maven Project功能的Import(菜單文件-> Import…)將pom.xml導入Eclipse 。
圖1:將現有的Maven項目導入Eclipse
導入完成后,名為com.javacodegeeks.redis的項目(或只是redis ,具體取決于您的導入設置)應出現在Eclipse Project Explorer視圖中。
圖2. Eclipse Project視圖中的com.javacodegeeks.redis
5.在Spring數據Redis上配置獨立Redis
Jedis的Redis配置從定義JedisConnectionFactory開始。 默認情況下,Jedis使用連接池( http://en.wikipedia.org/wiki/Connection_pool ),以便每次都不創建到Redis服務器的連接,而是從可用連接池中借用它們。 總的來說,這被認為是一種好的做法,因為創建網絡連接的過程是一個相對昂貴的操作。
讓我們將連接池和連接工廠定義為單獨的Spring配置bean,以便可以由不同的應用程序配置獨立地導入它。
package com.javacodegeeks.redis;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.Protocol;@Configuration public class ConnectionConfiguration {@Beanpublic JedisPoolConfig poolConfig() {final JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setTestOnBorrow( true );jedisPoolConfig.setMaxTotal( 10 );return jedisPoolConfig;}@Beanpublic JedisConnectionFactory connectionFactory() {final JedisConnectionFactory connectionFactory = new JedisConnectionFactory( poolConfig() ); connectionFactory.setHostName( "redis-host" );connectionFactory.setDatabase( Protocol.DEFAULT_DATABASE );connectionFactory.setPort( Protocol.DEFAULT_PORT ); return connectionFactory;} }在此代碼段中,我們將連接工廠配置為在具有最多10個連接池的redis-host上運行的Redis實例。 test on borrow設置實際上確保從池借用的連接仍然有效并且可以使用(否則將重新創建連接)。
6.配置與分片(分區)Redis的連接
在第4部分 Redis Sharding中 ,我們討論了客戶端分區。 實際上,Jedis提供了此功能,但不幸的是Spring Data Redis尚不支持此功能。
7.配置與Redis群集的連接
在第5部分“ Redis群集”中 ,我們發現了Redis的群集功能,并提到客戶端應該支持和識別Redis協議中的更改,以便向正確的節點發出命令。 Jedis已經提供了對Redis群集的支持,但是不幸的是Spring Data Redis尚不支持此功能。
8.使用Spring Data Redis訪問Redis
Spring Data Redis在不同的Redis客戶端上提供一致而簡潔的編程抽象(請參閱選擇Redis Java客戶端)。 這種抽象的核心是模板的概念:最簡單的方法提供對所需功能的訪問,而無需花費大量時間編寫樣板代碼。 如果是Redis,則為RedisTemplate 。
從本教程的前面的部分中,我們知道Redis支持多種原始數據類型:字符串和數字。 但是Java類型系統比這要豐富得多,這就是為什么RedisTemplate要求鍵的類型和值的類型(以及這些類型的序列化器)進行操作的原因。 我們將從一個簡單的示例開始,在該示例中,鍵和值只是字符串(實際上, Spring Data Redis已經包含了一個名為StringRedisTemplate的類,但盡管如此,讓我們看一下它的一般概念)。
package com.javacodegeeks.redis;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer;@Configuration @Import( value = ConnectionConfiguration.class ) public class ApplicationConfiguration {@Bean @Autowiredpublic RedisTemplate< String, String > redisTemplate( final JedisConnectionFactory connectionFactory ) { final RedisTemplate< String, String > template = new RedisTemplate< String, String >(); template.setConnectionFactory( connectionFactory );template.setKeySerializer( new StringRedisSerializer() );template.setHashValueSerializer( new StringRedisSerializer() );template.setHashKeySerializer( new StringRedisSerializer() );template.setValueSerializer( new StringRedisSerializer() );template.setStringSerializer( new StringRedisSerializer() );return template;} }這樣,我們就可以編寫我們的第一個測試了。 我們將要創建的所有測試用例的容器是一個名為RedisStringsTestCase的類,該類大量使用Spring Test腳手架提供的測試功能。
package com.javacodegeeks.redis;import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat;import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith( SpringJUnit4ClassRunner.class ) @ContextConfiguration( classes = ApplicationConfiguration.class ) public class RedisStringsTestCase {@Autowired private RedisTemplate< String, String > template;// Out tests are going to be there }通常,對于Redis命令的每種類別(請參閱第2部分 , Redis命令–使用Redis命令行 ), RedisTemplate具有從“ ops ”(opsForValue,opsForList,opsForHash等)開始的fa?ade方法,該方法從字面上返回一對一的一種類別特定命令到Java方法調用的映射。 第一個測試使用SET命令存儲一些鍵/值,并立即使用GET命令來驗證它是否正確存儲。
@Test public void testSetAndGet() {template.opsForValue().set( "mykey", "myvalue" );assertThat( template.opsForValue().get( "mykey"), equalTo( "myvalue" ) ); }為了確保測試不會失敗,我們可以使用redis-cli工具并連接到redis-host實例來檢查mykey值是否為“ myvalue ”。
圖3.驗證mykey值是否確實存儲在redis-host實例上
在轉到下一個測試用例之前,需要考慮一個問題:上一個測試完成執行后, mykey將保留在Redis中,直到有人將其刪除為止。 這種行為可能會導致其他測試用例失敗,通常被認為是不良做法。 最好使用干凈的數據庫開始每個測試,實際上我們將使它像這樣工作。 清除當前Redis數據庫的命令是FLUSHDB 。 它不是直接由RedisTemplate公開的,但是可以通過使用execute()方法并在基礎RedisConnection上調用flushDb()來輕松訪問和觸發。
@Before public void setUp() {template.execute( new RedisCallback< Void >() {@Overridepublic Void doInRedis( RedisConnection connection ) throws DataAccessException {connection.flushDb();return null;}} ); }我們將要探索的下一個操作是INCREMENT命令,該命令演示了字符串和包含數字的字符串之間的透明操作是如何進行的。
@Test public void testSetAndIncrementAndGet() {template.opsForValue().set( "mykey", "10" );template.opsForValue().increment( "mykey", 5 );assertThat( template.opsForValue().get( "mykey"), equalTo( "15" ) ); }足夠簡單,讓我們進入更復雜的數據結構:列表,集合和排序集合。 第一個測試用例創建一個值列表“ a ”,“ b ”,“ c ”,“ d ”(使用RPUSH命令)。 然后它檢查列表(大小LLEN命令),請求由索引(該列表的最后一個元素LINDEX命令),最后從列表(彈出所述第一元件LPOP命令)。
@Test public void testPushToListAndGetElementByIndexAndPopFirstElement() {template.opsForList().rightPushAll( "mykey", "a", "b", "c", "d" );assertThat( template.opsForList().size( "mykey" ), equalTo( 4L ) );assertThat( template.opsForList().index( "mykey", 3 ), equalTo( "d" ) );assertThat( template.opsForList().leftPop( "mykey" ), equalTo( "a" ) );assertThat( template.opsForList().size( "mykey"), equalTo( 3L ) ); }該代碼看起來非常緊湊且易讀。 讓我們從列表轉到集,然后下一個測試用例創建一組值“ a ”,“ b ”,“ c ”,“ d ”(使用SADD命令)。 然后,它檢查集合的大小(使用SCARD命令),并詢問“ c ”和“ e ”是否是該集合的成員(使用SISMEMBER命令)。
@Test public void testAddToSetAndCheckElementExists() {template.opsForSet().add( "mykey", "a", "b", "c", "d" );assertThat( template.opsForSet().size( "mykey" ), equalTo( 4L ) );assertThat( template.opsForSet().isMember( "mykey", "c" ), equalTo( true ) );assertThat( template.opsForSet().isMember( "mykey", "e" ), equalTo( false ) ); }組示出了全功率向上在幀間的一組操作:交叉點( SINTER命令),接頭( SUNION命令)和差( SDIFF命令)。 下面的測試案例通過將這些操作應用于兩組來演示該操作。
@Test public void testIntersetOperations() {template.opsForSet().add( "mykey1", "a", "b", "c", "d" );template.opsForSet().add( "mykey2", "c", "d", "e", "f" );assertThat( template.opsForSet().intersect( "mykey1", "mykey2" ), equalTo( set( "c", "d" ) ) );assertThat( template.opsForSet().union( "mykey1", "mykey2" ), equalTo( set( "a", "b", "c", "d", "e", "f" ) ) );assertThat( template.opsForSet().difference( "mykey1", "mykey2" ), equalTo( set( "a", "b" ) ) ); }為了完成數據收集類型,我們將介紹Spring Data Redis稱為ZSets的排序集。 下面的測試用例創建一個排序集( ZADD命令),然后要求Redis返回按分數從高到低排序的所有成員(帶有WITHSCORE選項的ZREVRANGEBYSCORE命令)。
@Test public void testAddToSortedSetAndCheckElementsAreSortedByScore() {template.opsForZSet().add( "mykey", "a", 6.15d );template.opsForZSet().add( "mykey", "b", 9.95d );template.opsForZSet().add( "mykey", "c", 8.45d );assertThat( template.opsForZSet().reverseRangeByScoreWithScores( "mykey", 0d, 10d ),equalTo( set( ( TypedTuple< String > )new DefaultTypedTuple< String >( "b", 9.95d ), ( TypedTuple< String > )new DefaultTypedTuple< String >( "a", 6.15d ), ( TypedTuple< String > )new DefaultTypedTuple< String >( "c", 8.45d ) ) ) ); }由于需要進行通用類型轉換,因此代碼有點冗長,但通常也很簡單且可讀性強。
最后,我們將把注意力轉移到哈希上。 Redis哈希可以被認為是Java中的數據對象:屬性(或字段)及其值的容器。 下一個測試用例(使用HSET命令)創建具有兩個屬性(或字段),“ prop1 ”和“ prop2 ”的哈希 。 然后,它驗證所有屬性及其值是否正確存儲(使用HGETALL命令),從哈希中刪除所有屬性(字段)(使用HDEL命令),并檢查它們是否確實被刪除(使用HGET命令)。
@Test public void testHashOperations() {template.opsForHash().put( "mykey", "prop1", "value1" );template.opsForHash().put( "mykey", "prop2", "value2" ); assertThat( template.opsForHash().entries( "mykey" ), equalTo( map( "prop1", "value1", "prop2", "value2" ) ) );assertThat( template.opsForHash().get( "mykey", "prop1" ), equalTo( ( Object )"value1" ) );template.opsForHash().delete( "mykey", "prop1", "prop2" );assertThat( template.opsForHash().get( "mykey", "prop1" ), equalTo( null ) ); }在本節中,我們介紹了Spring Data Redis的一些基礎知識,并很好地理解了Redis命令如何映射到其API。 我們開發的測試用例的數量只是瞥了一眼豐富的Spring Data Redis功能集。 在接下來的三個部分中,我們將研究高級API模式:事務,管道和發布/訂閱。
9.使用Spring Data Redis進行事務
盡管Redis交易支持在一定程度上受到限制,但是在需要時它仍然是一個非常有用的功能。 為了展示Spring Data Redis如何支持Redis事務語義,我們將創建一個測試用例:
- 為兩個鍵分配一些值: mykey1 ( SET命令)和mykey2 ( SADD命令)
- 驗證成員“ a ”不在mykey2集中( SISMEMBER命令)
- 開始監視密鑰mykey1 ( WATCH命令)
- 啟動事務( MULTI命令)
- 遞增mykey1 ( INCREMENT命令)
- 將新成員“ b ”添加到集合mykey2 ( SADD命令)
- 通過發出EXEC命令來完成事務
但是,我們忽略了template.execute()方法調用的返回值,它返回每個命令的結果。 在我們的測試案例中, INCREMENT的結果為15 , SADD的結果為1 。
10.使用Spring Data Redis進行流水線
我們大部分時間訪問Redis的方式是單個命令/響應序列:為了發送新命令,客戶端應等待Redis服務器返回上一個命令的結果。 但是,有一種方法可以將多個命令發送到服務器,而無需等待任何響應,最后一步即可讀取所有響應。 這種技術稱為pipelining 。
Redis從很早的發行版開始就支持流水線化,因此無論您運行的是哪個版本,都可以在Redis中使用流水線化(有關更多詳細信息,請參見http://redis.io/topics/pipelining )。
流水線可通過減少網絡延遲來顯著提高應用程序的性能。 但是有一個陷阱:當任何客戶端使用流水線技術發送命令時,服務器將被迫將響應排隊在內存中。 如果需要通過管道傳遞大量命令,則最好將這些命令發送到給定的合理數量(以便將它們拆分為多個管道)。 性能將幾乎相同,但使用的額外內存將受到限制。
以下測試案例演示了如何使用Spring Data Redis進行流水線操作。 我們將使用流水線發送100條命令,并通過將計數器的值與預期值進行比較來驗證是否已發送并處理了所有命令。
@Test public void testPipelining() {template.opsForValue().set( "mykey1", "10" ); template.executePipelined( new RedisCallback< Object >() {@Overridepublic Object doInRedis(RedisConnection connection) throws DataAccessException {for( int i = 0; i < 100; ++i ) {template.opsForValue().increment( "mykey1", 1 );}return null;}} );assertThat( template.opsForValue().get( "mykey1"), equalTo( "110" ) ); }與Redis事務測試用例一樣,我們忽略了template.executePipelined()方法調用的返回值,但它返回每個命令的結果(總共100個結果)。 另外,如果您想知道為什么我們從RedisCallback返回null ,則是有原因的:此返回值將被響應中的實際值(收到時)覆蓋,因此該回調不允許返回非null值(請參閱請訪問http://docs.spring.io/spring-data/data-redis/docs/1.2.0.RELEASE/reference/html/redis.html#pipeline了解更多信息)。
11.使用Spring Data Redis發布/訂閱
Redis支持發布/訂閱消息傳遞范例, Spring Data Redis也提供對此功能的全面支持。
從本質上講,發布/訂閱消息傳遞至少涉及兩個參與者:發布消息的發布者和偵聽發布者的消息的訂閱者(通常是多對多關系,但我們已將其簡化為單個發布者/訂閱者模型)。
為此開發一個健壯的測試用例可能會有些棘手。 發布是很容易的部分,但是在特定渠道(或模式)上偵聽消息需要做一些工作。 我們首先定義稱為RedisMessageListener的訂戶類。 它不會做很多,但會計算到目前為止已收到的所有消息。
package com.javacodegeeks.redis;import java.util.concurrent.atomic.AtomicInteger;import org.springframework.data.redis.connection.Message; import org.springframework.data.redis.connection.MessageListener;public class RedisMessageListener implements MessageListener {private AtomicInteger count = new AtomicInteger( 0 ); @Overridepublic void onMessage(Message message, byte[] pattern) {count.incrementAndGet();}public int getCount() {return count.get();} }接下來,我們應該使用RedisMessageListener和RedisMessageListenerContainer其他bean擴展配置。 后者的作用非常重要:它將聽眾和他們正在收聽的頻道粘合在一起。 PubsubConfiguration我們開始所需的最低配置( PubsubConfiguration )(請注意,我們正在導入之前創建的ApplicationConfiguration )。
package com.javacodegeeks.redis;import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.data.redis.connection.MessageListener; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.listener.ChannelTopic; import org.springframework.data.redis.listener.RedisMessageListenerContainer;@Configuration @Import( value = ApplicationConfiguration.class ) public class PubsubConfiguration {@Bean @Autowiredpublic RedisMessageListenerContainer container( final JedisConnectionFactory connectionFactory ) { final RedisMessageListenerContainer container = new RedisMessageListenerContainer();container.setConnectionFactory( connectionFactory );container.addMessageListener( listener(), new ChannelTopic( "test-channel" ) );return container;}@Beanpublic MessageListener listener() {return new RedisMessageListener();} }為了提供一些背景信息,我們將偵聽器附加到名為“ test-channel ” 的通道 ,這就是我們要向其發布消息的通道。
發布/訂閱消息傳遞通信本質上是異步的,這是在開發這種功能的測試用例時的又一個復雜問題。 訂戶將不會立即接收消息,但是會有些延遲。 如果要連接到本地計算機上運行的Redis服務器,則可能需要花費毫秒,但是如果要訪問云中的某個實例,則可能需要一段時間。 一種可能的處理方法是引入某種合理的延遲,以便給訂戶一些時間來接收所有消息(這也是我們在測試案例中使用的技巧)。
package com.javacodegeeks.redis;import static com.jayway.awaitility.Awaitility.await; import static java.util.concurrent.TimeUnit.SECONDS; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat;import java.util.concurrent.Callable;import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith( SpringJUnit4ClassRunner.class ) @ContextConfiguration( classes = PubsubConfiguration.class ) public class RedisPublishSubscriberTestCase {@Autowired private RedisTemplate< String, String > template;@Autowired private RedisMessageListener listener;@Testpublic void testPublishSubscribe() {assertThat( listener.getCount(), equalTo( 0 ) );template.convertAndSend( "test-channel", "Test Message 1!" );template.convertAndSend( "test-channel", "Test Message 2!" );template.convertAndSend( "test-channel", "Test Message 3!" );await().atMost( 1, SECONDS ).until(new Callable< Integer >() { @Overridepublic Integer call() throws Exception {return listener.getCount();}}, equalTo( 3 ) );} }這個新的測試案例使用我們的PubsubConfiguration類實例化Spring測試上下文。 在測試用例本身中,我們將三個消息發布到Redis服務器上的“ test-channel ” 通道 。 然后,我們給消息偵聽器一些時間(但不超過一秒),以消耗通道上發布的所有消息。 之后,我們期望偵聽器收到所有3條消息,這就是我們最后要驗證的內容。
12.結論
Redis的發展非常Swift。 跟上它的所有新功能和命令非常困難。 這樣,您可能會發現Spring Data Redis尚不支持最新Redis發行版中提供的某些最新功能(甚至Java客戶端也需要一些時間來添加對它的支持)。 一個很好的例子是Redis Cluster, Spring Data Redis尚不支持它。
這是Redis教程的最后一部分,但這只是通往Redis世界的開始。 如果您想關注Redis的最新發展,可以參考以下兩個資源:
- http://antirez.com/:Redis的創建者Salvatore Sanfilippo的博客
- http://aphyr.com/posts/283-call-me-maybe-redis :關于Redis群集可用性的非常有用的見解
翻譯自: https://www.javacodegeeks.com/2015/09/spring-data-and-redis.html
總結
以上是生活随笔為你收集整理的Spring数据和Redis的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java 模块化osgi_OSGi简介–
- 下一篇: WildFly 10 CR 2发布– J