spring data redis - jedisConnectionFactory and redisTemplate

转载自:spring data redis官方文档

5.1. Redis Requirements

Spring Redis requires Redis 2.6 or above and Spring Data Redis integrates with Lettuce and Jedis, two popular open-source Java libraries for Redis.

5.2. Redis Support High-level View

The Redis support provides several components. For most tasks, the high-level abstractions and support services are the best choice. Note that, at any point, you can move between layers. For example, you can get a low-level connection (or even the native library) to communicate directly with Redis.

5.3. Connecting to Redis

One of the first tasks when using Redis and Spring is to connect to the store through the IoC container. To do that, a Java connector (or binding) is required. No matter the library you choose, you need to use only one set of Spring Data Redis APIs (which behaves consistently across all connectors): the org.springframework.data.redis.connection package and its RedisConnection and RedisConnectionFactory interfaces for working with and retrieving active connections to Redis.

5.3.1. RedisConnection and RedisConnectionFactory

RedisConnection provides the core building block for Redis communication, as it handles the communication with the Redis back end. It also automatically translates the underlying connecting library exceptions to Spring’s consistent DAO exception hierarchy so that you can switch the connectors without any code changes, as the operation semantics remain the same.

For the corner cases where the native library API is required, RedisConnection provides a dedicated method (getNativeConnection) that returns the raw, underlying object used for communication.

Active RedisConnection objects are created through RedisConnectionFactory. In addition, the factory acts as PersistenceExceptionTranslator objects, meaning that, once declared, they let you do transparent exception translation. For example, you can do exception translation through the use of the @Repository annotation and AOP. For more information, see the dedicated section in the Spring Framework documentation.

Depending on the underlying configuration, the factory can return a new connection or an existing connection (when a pool or shared native connection is used).

The easiest way to work with a RedisConnectionFactory is to configure the appropriate connector through the IoC container and inject it into the using class.

Unfortunately, currently, not all connectors support all Redis features. When invoking a method on the Connection API that is unsupported by the underlying library, an UnsupportedOperationException is thrown.
5.3.3. Configuring the Jedis Connector

Jedis is one of the connectors supported by the Spring Data Redis module through the org.springframework.data.redis.connection.jedis package. In its simplest form, the Jedis configuration looks as follow:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <!-- Jedis ConnectionFactory -->
  <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"/>

</beans>

For production use, however, you might want to tweak settings such as the host or password, as shown in the following example:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="server" p:port="6379" />

</beans>
5.4. Redis Sentinel Support

For dealing with high-availability Redis, Spring Data Redis has support for Redis Sentinel, using RedisSentinelConfiguration, as shown in the following example:

/**
 * jedis
 */
@Bean
public RedisConnectionFactory jedisConnectionFactory() {
  RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
  .master("mymaster")
  .sentinel("127.0.0.1", 26379)
  .sentinel("127.0.0.1", 26380);
  return new JedisConnectionFactory(sentinelConfig);
}

/**
 * Lettuce
 */
@Bean
public RedisConnectionFactory lettuceConnectionFactory() {
  RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
  .master("mymaster")
  .sentinel("127.0.0.1", 26379)
  .sentinel("127.0.0.1", 26380);
  return new LettuceConnectionFactory(sentinelConfig);
}

RedisSentinelConfiguration can also be defined with a PropertySource, which lets you set the following properties:

Configuration Properties
  • spring.redis.sentinel.master: name of the master node.

  • spring.redis.sentinel.nodes: Comma delimited list of host:port pairs.

Sometimes, direct interaction with one of the Sentinels is required. Using RedisConnectionFactory.getSentinelConnection() or RedisConnection.getSentinelCommands() gives you access to the first active Sentinel configured.

5.5. Working with Objects through RedisTemplate

Most users are likely to use RedisTemplate and its corresponding package, org.springframework.data.redis.core. The template is, in fact, the central class of the Redis module, due to its rich feature set. The template offers a high-level abstraction for Redis interactions. While RedisConnection offers low-level methods that accept and return binary values (byte arrays), the template takes care of serialization and connection management, freeing the user from dealing with such details.

Moreover, the template provides operations views (following the grouping from the Redis command reference) that offer rich, generified interfaces for working against a certain type or certain key (through the KeyBound interfaces) as described in the following table:

Table 1. Operational views
Interface Description

Key Type Operations

GeoOperations

Redis geospatial operations, such as GEOADDGEORADIUS,…​

HashOperations

Redis hash operations

HyperLogLogOperations

Redis HyperLogLog operations, such as PFADDPFCOUNT,…​

ListOperations

Redis list operations

SetOperations

Redis set operations

ValueOperations

Redis string (or value) operations

ZSetOperations

Redis zset (or sorted set) operations

Key Bound Operations

BoundGeoOperations

Redis key bound geospatial operations

BoundHashOperations

Redis hash key bound operations

BoundKeyOperations

Redis key bound operations

BoundListOperations

Redis list key bound operations

BoundSetOperations

Redis set key bound operations

BoundValueOperations

Redis string (or value) key bound operations

BoundZSetOperations

Redis zset (or sorted set) key bound operations

Once configured, the template is thread-safe and can be reused across multiple instances.

RedisTemplate uses a Java-based serializer for most of its operations. This means that any object written or read by the template is serialized and deserialized through Java. You can change the serialization mechanism on the template, and the Redis module offers several implementations, which are available in the org.springframework.data.redis.serializer package. See Serializers for more information. You can also set any of the serializers to null and use RedisTemplate with raw byte arrays by setting the enableDefaultSerializer property to false. Note that the template requires all keys to be non-null. However, values can be null as long as the underlying serializer accepts them. Read the Javadoc of each serializer for more information.

For cases where you need a certain template view, declare the view as a dependency and inject the template. The container automatically performs the conversion, eliminating the opsFor[X] calls, as shown in the following example:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <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"/>
  ...

</beans>
public class Example {

  // inject the actual template
  @Autowired
  private RedisTemplate<String, String> template;

  // inject the template as ListOperations
  @Resource(name="redisTemplate")
  private ListOperations<String, String> listOps;

  public void addLink(String userId, URL url) {
    listOps.leftPush(userId, url.toExternalForm());
  }
}

5.6. String-focused Convenience Classes

Since it is quite common for the keys and values stored in Redis to be java.lang.String, the Redis modules provides two extensions to RedisConnection and RedisTemplate, respectively the StringRedisConnection (and its DefaultStringRedisConnection implementation) and StringRedisTemplate as a convenient one-stop solution for intensive String operations. In addition to being bound to String keys, the template and the connection use the StringRedisSerializerunderneath, which means the stored keys and values are human-readable (assuming the same encoding is used both in Redis and your code). The following listings show an example:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

  <bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:use-pool="true"/>

  <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" p:connection-factory-ref="jedisConnectionFactory"/>
  ...
</beans>
public class Example {

  @Autowired
  private StringRedisTemplate redisTemplate;

  public void addLink(String userId, URL url) {
    redisTemplate.opsForList().leftPush(userId, url.toExternalForm());
  }
}

As with the other Spring templates, RedisTemplate and StringRedisTemplate let you talk directly to Redis through the RedisCallback interface. This feature gives complete control to you, as it talks directly to the RedisConnection. Note that the callback receives an instance of StringRedisConnection when a StringRedisTemplate is used. The following example shows how to use the RedisCallback interface:

public void useCallback() {

  redisTemplate.execute(new RedisCallback<Object>() {
    public Object doInRedis(RedisConnection connection) throws DataAccessException {
      Long size = connection.dbSize();
      // Can cast to StringRedisConnection if using a StringRedisTemplate
      ((StringRedisConnection)connection).set("key", "value");
    }
   });
}
5.7. Serializers

From the framework perspective, the data stored in Redis is only bytes. While Redis itself supports various types, for the most part, these refer to the way the data is stored rather than what it represents. It is up to the user to decide whether the information gets translated into strings or any other objects.

In Spring Data, the conversion between the user (custom) types and raw data (and vice-versa) is handled Redis in the org.springframework.data.redis.serializer package.

This package contains two types of serializers that, as the name implies, take care of the serialization process:

  • Two-way serializers based on RedisSerializer.

  • Element readers and writers that use RedisElementReader and RedisElementWriter.

The main difference between these variants is that RedisSerializer primarily serializes to byte[] while readers and writers use ByteBuffer.

Multiple implementations are available (including two that have been already mentioned in this documentation):

  • JdkSerializationRedisSerializer, which is used by default for RedisCache and RedisTemplate.

  • the StringRedisSerializer.

However one can use OxmSerializer for Object/XML mapping through Spring OXM support or Jackson2JsonRedisSerializeror GenericJackson2JsonRedisSerializer for storing data in JSON format.

Do note that the storage format is not limited only to values. It can be used for keys, values, or hashes without any restrictions.

By default, RedisCache and RedisTemplate are configured to use Java native serialization. Java native serialization is known for allowing remote code execution caused by payloads that exploit vulnerable libraries and classes injecting unverified bytecode. Manipulated input could lead to unwanted code execution in the application during the deserialization step. As a consequence, do not use serialization in untrusted environments. In general, we strongly recommend any other message format (such as JSON) instead.

If you are concerned about security vulnerabilities due to Java serialization, consider the general-purpose serialization filter mechanism at the core JVM level, originally developed for JDK 9 but backported to JDK 8, 7, and 6:



猜你喜欢

转载自blog.csdn.net/qq_26222859/article/details/80282517