1.spring-data-redis如何连接到redis服务端
其中定义了两个接口 org.springframework.data.redis.connection下的RedisConnection和RedisConnectionFactory工厂接口:
public interface RedisConnection extends RedisCommands { void close() throws DataAccessException; boolean isClosed(); Object getNativeConnection(); boolean isQueueing(); boolean isPipelined(); void openPipeline(); List<Object> closePipeline(); }
其中RedisCommands接口定义了redis支持的所有操作接口,
public interface RedisConnectionFactory extends PersistenceExceptionTranslator { RedisConnection getConnection(); }
RedisConnectionFactory接口只定义一个获取连接的方法,而PersistenceExceptionTranslator定义了出现异常时把异常转化为spring通用的DataAccessException异常,可以供spring统一处理。
spring-data-redis通过三种方式连接:
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="server" p:port="6379"/>
<bean id="jredisConnectionFactory" class="org.springframework.data.redis.connection.jredis.JredisConnectionFactory" p:host-name="server" p:port="6379"/>
<bean id="jredisConnectionFactory" class="org.springframework.data.redis.connection.rjc.RjcConnectionFactory" p:host-name="server" p:port="6379"/>
而spring-data-redis是统一通过RedisTemplate类给用户操作
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:use-pool="true"/> <!-- redis template definition --> <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" p:connection-factory-ref="jedisConnectionFactory"/>
示例如下:
public class Example { // inject the actual template @Autowired private RedisTemplate<String, String> template; // inject the template as ListOperations @Autowired private ListOperations<String, String> listOps; public void addLink(String userId, URL url) { listOps.leftPush(userId, url.toExternalForm()); } }
2.序列化
通过序列化接口org.springframework.data.redis.serializer来定制自己的序列化逻辑
public interface RedisSerializer<T> {
/** * Serialize the given object to binary data. * * @param t object to serialize * @return the equivalent binary data */ byte[] serialize(T t) throws SerializationException; /** * Deserialize an object from the given binary data. * * @param bytes object binary representation * @return the equivalent object instance */ T deserialize(byte[] bytes) throws SerializationException; }
存到redis上都是二进制的值,现在spring-data-redis里面已经提供了几种序列化机制:
JacksonJsonRedisSerializer json格式序列化
JdkSerializationRedisSerializer jdk的序列化
OxmSerializer spring的orm的序列化
StringRedisSerializer 简单的字符串跟字节转换序列化
3.spring-data-redis的消息发布订阅处理
<!-- this is the Message Driven POJO (MDP) -->
<bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter"> <constructor-arg> <bean class="redisexample.DefaultMessageDelegate"/> </constructor-arg> </bean> <!-- and this is the message listener container... --> <bean id="redisContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer"> <property name="connectionFactory" ref="connectionFactory"/> <property name="messageListeners"> <!-- map of listeners and their associated topics (channels or/and patterns) --> <map> <entry key-ref="messageListener"> <bean class="org.springframework.data.redis.listener.ChannelTopic"> <constructor-arg value="chatroom"> </bean> </entry> </map> </property> </bean>
每次接收到消息,就会调用注册的listener来处理。
4.支持spring cache的处理抽象
<bean id="cacheManager" class="org.springframework.data.redis.cache.RedisCacheManager" c:template-ref="redisTemplate">
这样支持在本地缓存访问过的记录。
5.访问redis时支持回调,给程序员开发充分的扩展性灵活性来处理自定义的一些操作
通过扩展回调接口:
public interface RedisCallback<T> {
/** * Gets called by {@link RedisTemplate} with an active Redis connection. Does not need to care about activating or * closing the connection or handling exceptions. * * @param connection active Redis connection * @return a result object or {@code null} if none * @throws DataAccessException */ T doInRedis(RedisConnection connection) throws DataAccessException; }
这个接口可以直接操作connection对象,可以给开发充分的控制权进行操作。
然后通过调用redisTemplate的
public <T> T execute(RedisCallback<T> action) {
return execute(action, isExposeConnection()); } /** * Executes the given action object within a connection, which can be exposed or not. * * @param <T> return type * @param action callback object that specifies the Redis action * @param exposeConnection whether to enforce exposure of the native Redis Connection to callback code * @return object returned by the action */ public <T> T execute(RedisCallback<T> action, boolean exposeConnection) { return execute(action, exposeConnection, false); }
实际上redisTemplate的所有操作都是通过这个回调接口来处理的
public List<Object> exec() { return execute(new RedisCallback<List<Object>>() { public List<Object> doInRedis(RedisConnection connection) throws DataAccessException { return connection.exec(); } }); } public void delete(K key) { final byte[] rawKey = rawKey(key); execute(new RedisCallback<Object>() { public Object doInRedis(RedisConnection connection) { connection.del(rawKey); return null; } }, true); } public void delete(Collection<K> keys) { final byte[][] rawKeys = rawKeys(keys); execute(new RedisCallback<Object>() { public Object doInRedis(RedisConnection connection) { connection.del(rawKeys); return null; } }, true); }
回调接口代码看起来很优雅,也非常灵活,设计得很不错。