网站建设之前必须 域名备案,网站建设的意见建议,长春企业网站seo,深圳市建设工程网站本文是我们学院课程的一部分#xff0c;标题为Redis NoSQL键值存储 。 这是Redis的速成班。 您将学习如何安装Redis并启动服务器。 此外#xff0c;您将在Redis命令行中乱七八糟。 接下来是更高级的主题#xff0c;例如复制#xff0c;分片和集群#xff0c;同时还介绍了… 本文是我们学院课程的一部分标题为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开发人员的常用工具集包括JDKJava开发工具包和类似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 xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.javacodegeeks/groupIdartifactIdredis/artifactIdversion0.0.1-SNAPSHOT/versionpackagingjar/packagingpropertiesproject.build.sourceEncodingUTF-8/project.build.sourceEncodingspring.version4.0.2.RELEASE/spring.version/propertiesdependenciesdependencygroupIdorg.springframework.data/groupIdartifactIdspring-data-redis/artifactIdversion1.2.0.RELEASE/version/dependencydependencygroupIdredis.clients/groupIdartifactIdjedis/artifactIdversion2.4.1/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-core/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-tx/artifactIdversion${spring.version}/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-context/artifactIdversion${spring.version}/version/dependencydependencygroupIdch.qos.logback/groupIdartifactIdlogback-classic/artifactIdversion1.0.13/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-test/artifactIdversion${spring.version}/versionscopetest/scope/dependencydependencygroupIdorg.hamcrest/groupIdartifactIdhamcrest-all/artifactIdversion1.3/versionscopetest/scope/dependencydependencygroupIdcom.jayway.awaitility/groupIdartifactIdawaitility/artifactIdversion1.5.0/versionscopetest/scope/dependencydependencygroupIdjunit/groupIdartifactIdjunit/artifactIdversion4.11/versionscopetest/scope/dependency/dependenciesbuildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdconfigurationsource1.7/sourcetarget1.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 ”opsForValueopsForListopsForHash等开始的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命令来完成事务 Test
public void testTransaction() {template.opsForValue().set( mykey1, 10 ); template.opsForSet().add( mykey2, a ); assertThat( template.opsForSet().isMember( mykey2, b), equalTo( false ) );template.execute( new SessionCallback List Object () {SuppressWarnings(unchecked)Overridepublic K, V ListObject execute( final RedisOperations K, V operations )throws DataAccessException {operations.watch( ( K )mykey1 );operations.multi(); operations.opsForValue().increment( ( K )mykey1, 5 );operations.opsForSet().add( ( K )mykey2, ( V )b );return operations.exec();}} );assertThat( template.opsForValue().get( mykey1), equalTo( 15 ) );assertThat( template.opsForSet().isMember( mykey2, b), equalTo( true ) );
} 但是我们忽略了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