Spring Certified China Education Management Center – Spring Data Redis Frame Tutorial

8.1. File structure

This part of the reference document explains the core function provided by Spring Data Redis. It explains the concept and semantics of the key value module and the syntax of various store namespaces. For a description of the key value storage, Spring or Spring Data example, see Learning NOSQL and key value storage. This document only involves Spring Data Redis support and assumes that users are familiar with key value storage and Spring concepts.

"Redis Support" introduces the REDIS module function set.

"Redis repositories" introduced the repository support for Redis.

This document is a reference guide supported by Spring Data Redis (SDR).

9. Why use Spring Data Redis?

Spring Framework is the leading full stack Java / Jee application framework. It provides a lightweight container and a non-invasive programming model by using dependent injection, AOP and portable service abstraction.

The NOSQL storage system provides alternatives for classic RDBMS to achieve horizontal scalability and speed. In terms of implementation, key value storage represents one of the largest (the oldest) members in NOSQL space.

The Spring Data Redis (SDR) framework has eliminated the redundant tasks and template code required to store interactions through the Spring, so that the Spring application stored using the Redis key value can be easily written.

10. Redis support

One of the key value stores supported by Spring Data is REDIS. Quote Redis Project Home:

Redis is a high-level key value storage. It is similar to memcached, but the data set is not volatile, the value can be a string, just like in Memcached, but it can be a list, a collection, and an ordered collection. All of these data types can be operated by atomic operations to push / pop up elements, add / delete elements, execute differences between the server side and integrate, intersection, and collections. Redis supports different types of sorting capabilities.

Spring Data Redis provides features that easily configure and access Redis from the Spring application. It provides low and advanced abstraction with store interaction, using users to get rid of the infrastructure concerns.

10.1. Getting started

A simple way to set up a working environment is to create a Spring-based project in STS.

First, you need to set up a REDIS server that is running.

Create a Spring item in STS:

Go to the file New Spring Template Project Simple Spring Utility Project, and press if prompts appear. Then enter the item and package name, such as org.spring.redis.example. Add the following to the POM.xml file Dependencies element: org.springframework.Data Spring-data-redis 2.6.0

Change the version of Spring in pom.xml to 5.3.13

Add the following location of the Maven Spring Milestone repository to your POM.xml element, make it in the same level with your element: Spring-milestone Spring Maven Milestone repository https://repo.spring.io/libs-milestone

The repository can also be viewed here.

10.2.Redis Requirements

Spring Redis requires Redis 2.6 or higher, and Spring Data Redis integrates with Lettuce and Jedis, which two popular Redis open source Java libraries.

10.3.Redis Supports advanced views

Redis supports several components. For most tasks, advanced abstractions and support services are the best choice. Please note that you can move between layers at any time. For example, you can get a low-level connection (even this unit) to communicate directly with Redis.

10.4. Connect to REDIS

One of the primary tasks when using Redis and Spring is to connect to the storage via the IOC container. To do this, a Java connector (or binding) is required. Whether you choose a library, you only need to use a set of spring redis’s API (this is a consistent behavior in all connector):

Org.springframework.data.redis.connection package and its RedisConnection and RedisConnectionFactory with work and retrieved active connection interfaces.

10.4.1.Redisconnection and RedisConnectionFactory

Redisconnection provides the core build block for Redis communication because it processes communication with the rear end of the Redis. It also automatically converts the underlying connection library to the Spring consistent DAO exception hierarchy so that you can switch the connector without changing any code because the operation semantic remains unchanged.

For extreme cases that require this Base’s API, RedisConnection provides a GetNativeConnection that returns the original underlying object for communication.

The active RedisConnection object is through RedisConnectionFactory. In addition, the factory is acting

The PersistenceExceptionTranslator object, which means that once declare, they can make you transparent abnormal conversion. For example, you can use @Repository annotations and AOP to translate abnormally. For more information, see the Special Section in the Spring Framework document.

Depending on the underlying configuration, the plant can return to a new connection or existing connection (when using a pool or sharing this phone).

The easiest way to use A RedisconnectionFactory is configured with an appropriate connector through the IOC container and injects the USING class.

Unfortunately, all connectors are currently supporting all REDIS functions. When the method is called on the Connection API that is not supported by the underlying library,

UNSUPPORTEDOPERATIONException will throw an AN. The following summary describes the functions supported by each REDIS connector:

10.4.2. Configuring a lettuce connector

LetTUCE is a Netty-based open source connector supported by Spring Data Redis.

Org.springframework.data.redis.connection.LetTuce.

Add the following to the POM.xml file defendencies element:

IO.LetTuce

Lettuce-core

6.1.5.5.Release

The following example shows how to create a new Lettuce connection factory:

@ConfigurationClass Appconfig {@bean

Public LettuceconnectionFactory RedisconnectionFactory {Return New LettuceconnectionFactory (New RedisstandaloneConfiguration ("Server", 6379));

}

}

There are also some way-upless connection parameters that can be adjusted. By default, LettuceConnection is shared by all instances that create all instances that create the same thread secure local connection for all non-blocking and non-transactional operations. To use a dedicated connection, set the sharenativeConnection to false. If set to, LettuceConnectionFactory can also be configured to use AletTucePool for pilot blocking and transaction connection or all connections.

SharenativeConnectionFalse

Lettuce is integrated with Netty’s native transfer, allowing you to communicate with Redis using UNIX domain. Make sure that the appropriate native transfer dependency that matches your runtime environment. The following example shows how to create a lettuce connection plant / var/run/redis.sock for UNIX domain sets / var/run/redis.sock:

Public LettuceConnectionFactory RedisconnectionFactory {Return New LettuceconnectionFactory ("/ var / run / redis.sock");

}

}

Netty currently supports Epoll (Linux) and KQUEUE (BSD / MacOS) interfaces for operating system native transmission.

10.4.3. Configure JEDIS Connector

Jedis is the Spring Data Redis module passed

Org.springframework.data.redis.connection.jedis Pack Supported Community Drive.

Redis.clients

Jedis

3.7.0

The simplest form of JEDIS is as follows:

Public JedisconnectionFactory RedisconnectionFactory {Return New JedisconnectionFactory;

}

}

However, for production purposes, you may need to adjust the host or password, etc., as shown below:

@ConfigurationClass Redisconfiguration {@bean

Public JEDISCONNECTIONFAACTORY RedisconnectionFactory {

RedisstandaloneConfiguration Config=New RedisstandaloneConfiguration ("Server", 6379); Return New JedisconnectionFactory (config)

}

}

10.4.4. Write the primary server, read from a copy

Redis Main / Copy Settings – No automatic failover (for automatic failover, see: Sports) – Not only allows data to be securely stored on more nodes. It also allows you to read data from the copy by using Lettuce while writing to the primary server. You can use the setup / write policy you want to use,

LettuceClientConfiguration as shown in the following example:

@ConfigurationClass WriteTomasterReadFromReplicAnfiguration {@bean

Public LettuceConnectionFactory RedisconnectionFactory {

LettuceclientConfiguration ClientConfig=LettuceClientConfiguration.builder

.readfrom (replica_preferred)

.

RedisstandaloneConfiguration ServerConfig=New RedisstandaloneConfiguration ("Server", 6379); Return New LettuceConnectionFactory (ServerConfig, ClientConfig);

}

}

For an environment that is non-public address is reported through the info command (for example, when using AWS), please use

RedisstaticMasterRreplicaconfiguration instead RedisstandalOneConfiguration. Note that RedisstaticMasterRreplicAnfiguration does not support PUB / SUB due to the lack of PUB / SUB messages across a single server.

10.5.Redis Sentinel Support

For processing high available Redis, Spring Data Redis has supported Redis Sentinel, use

REDISSENTINELCONFIGURATION, as shown in the following example:

@Beanpublic redisconnectionFactory JedisconnectionFactory {

RedissentinelConfiguration SentinelConfig=New RedissentinelConfiguration

.master ("mymaster")

.Sentinel ("127.0.0.1", 26379)

.Sentinel ("127.0.0.1", 26380); Return New JedisconnectionFactory (SentinelConfig);

@Beanpublic redisconnectionFactory LettuceConnectionFactory {

.master ("mymaster")

.Sentinel ("127.0.0.1", 26380); Return New LettuceConnectionFactory (SentinelConfig);

}

RedissentinelConfiguration can also define PropertySource, which allows you to set the following properties:

Configuration properties

Spring.redis.sentinel.master: The name of the primary node.

Spring.redis.sentinel.nodes: comma-separated host: port pair list.

Spring.redis.sentinel.password: The password applied when using Redis Sentinel to authenticate

Sometimes, you need to interact directly with one of them. use

RedisconnectionFactory.getSentinelConnection or RedisConnection.getSentinelCommands allows you to access the first activity SENTINEL.

10.6. Processing objects via Redistemplate

Most users may use redistemplate and their corresponding packages,

Org.springframework.data.redis.core. Due to its rich function set, the template is actually the central class of the Redis module. This template provides advanced abstraction to Redis interaction. Although RedisConnection provides a low-level method for accepting and returning a binary value (Byte array), the template is responsible for serializing and connect management, using the user from handling such details.

In addition, templates provide operational views (followed in the REDIS command reference), provide a wide range of common interfaces for a specific type or a specific key (via the keybound interface), as described below:

After configuration, the template is thread safe, and can be reused across multiple instances.

Redistemplate Most Operations use Java-based serialization programs. This means that any objects written or read by the template are serialized and deserialized by Java. You can change the serialization mechanism on the template, and the Redis module provides a variety of implementations.

Org.springframework.data.redis.serializer package is used. For more information, see the serialization program. You can also set any serialization to NULL and set the EnableDefaultSerializer property to RedisTemplate and the original byte array false. Note that the template requires all keys to be non-empty. However, as long as the underlying serialization procedure accepts them, the value can be empty. Read each serialization program Javadoc for more information.

For the case where a template view is required, the view is declared as a dependency and injected into the template. The container automatically performs conversion, eliminating Opsfor [x] call, as shown in the following example:

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 https://www.springframework.org/schema/beans/spring-beans.xsd">

Public class example {// incject the actual template

@Autowired

Private Redistemplate Template; // Inject The Template as ListOperations

@Resource (name="redistemplate") Private listopertens Listops; public void addlink (string userid, url url) {

Listops.leftpush (userid, url.toExternal;);

}

}

10.7. Convenient courses in string

Since the keys and values ??stored in the redis are common Java.lang.String, the Redis module provides the redisconnection and the two extended Redistemplate, respectively, StringRedisconnection (and

DEFAULTSTRINGREDISCONNECTION implementation) and StringRediStemplate’s convenient one-stop solution for intensive string operations. In addition to binding to the String key, template and connection use StringRedisserializer underlying, which means that the stored keys and values ??are human be readable (assuming to use the same encoding in Redis and your code). The following list shows an example:

Public class example {@Autowired

Private stringredistemplate redistemplate; public void addlink (string userid, url URL) {

Redistemplate.opsforList.Leship (UserID, URL.TOEXTERNALNALM);

}

}

Because of other Spring Templates, Redistemplate and StringRedistemplate let you pass the RedisCallback interface that conversation Redis. This feature allows you to completely control because it is directly with RedisConnection. Please note that callback receives the instance StringRedistemplate when using StringRedisconnectiona. The following example shows how to use the RedisCallback interface:

Public void usecallback {

Redistemplate.execute (new rediscallback {public object DOINREDIS (Redisconnection Connection) THROWS DataAccessException

Long size=connection.dbsize; // can cast to stringredisconnection if using a stringredistemplate

(Stringredisconnection) .SET ("Key", "Value");

}

});

}

10.8. Serializer

From the perspective of the framework, the data stored in the redis is only bytes. Although Redis itself supports various types, in most cases, these types refer to data storage mode, not what it represents. The user decides whether to convert the information into a string or any other object.

In Spring Data, the user (custom) type and the original data (vice versa) are converted

Org.springframework.data.redis.serializer package is processed by Redis.

This package contains two types of sequencer, as the name suggests, and they are responsible for serialization:

Based on Redisserializer.

Use the RedisElementReader and the element reader and writer RedisElementWriter.

The main difference between these variants is that the RedisSerializer is primarily byte to readers and authors use Bytebuffer.

There are many implementations available (including two of this document):

JDKSerializationRedisserializer, is used by Rediscache and Redistemplate by default.

Stringredisserializer.

However, you can support Object / XML mapping by Spring OXM.

Jackson2jsonredisserializer or GenericJackson2jsonRedisserializer is used to store data in JSON format.

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

By default, rediscache and redistemplate are configured to serialize natives using Java. Java native serializes to allow running remote code caused by payloads that use vulnerable libraries and classes that are not authenticated by unauthenticated bytecodes. Manipulating inputs may result in running unwanted code during the application during the deserialization step. Therefore, sequentialization is not used in an untrusted environment. Usually, we strongly recommend that you use any other message format (for example, JSON).

If you are worried about security vulnerabilities caused by Java serialization, consider the universal serial filter mechanism for the core JVM level, which was initially developed for JDK 9, but later ported to JDK 8, 7 and 6:

Filters the incoming serialized data.

JEP 290.

OWASP: Defense sequence of untrusted data.

Hash mapping

Data can be stored using various data structures in REDIS.

Jackson2jsonredisserializer can convert an object in JSON format. Ideally, you can store JSON as a value using a normal key. You can implement more complex structured object mappings by using the Redis Hash. Spring Data Redis provides a variety of strategies that map data to hash (depending on the case):

Direct mapping, by using the Hashoperts and serialization procedures

Use the Redis repository

Use HashMapper and HashOperations

10.9.1. Hash mappier

The hash mapping device is a mapping object to AMAP and the returned converter. Hashmapper is intended to be used with Redis Hash.

There are many implementations available:

Beanutilshashmapper uses Spring’s beanUtils.

ObjectHashmapper uses an object to a hash map.

Jackson2hashMapper uses Fasterxml Jackson.

The following example shows a method of implementing a hash mapping:

Public class person {

String dimstname;

String lastname; // …} public class hashmapping {@Autowired

Hashoperts hashopertless;

Hashmapper mappper=new objecthashmapper; public void writehash (string key, persons) {

Map mappedhash=mapper.tohash (person);

Hashopertitions.putall (Key, Mappedhash);

PUBLIC PERSON LOADHASH (String Key) {

Map loadedhash=hashopertyS.entries ("key"); return (person) mapper.fromhash (loadedhash);

}

}

10.9.2.jackson2hashmapper

Jackson2hashMapper provides Redis hash mappings using FASTERXML JACKSON. Jackson2HashMapper can map top attributes to hash literal names and can choose to flatten the structure. Simple type map to simple values. Complex type (nested object, collection, mapping, etc.) is expressed as nested JSON.

Exhibit creates a separate hash entry for all nested properties and analyze complex types as simple types as much as possible.

Consider the following classes and the data structure therebetween:

Public Class Person {String Firstname; String Lastname;

Address Address; Date Date;

Localdatetime localdatetime;

}

PUBLIC CLASS Address {String City;

}

The following table shows how data in the front class is displayed in the normal mapping:

Flatization requires all attribute names that do not interfere with the JSON path. When using the exhibition, it is not supported in the mapping button or used as a property name or parentheses. The generated hash cannot map back objects.

Java.util.date and java.util.calendar are represented in milliseconds. If the JSR-310 date / Time type is on the classpath, toString seizes its form Jackson-DataType-JSR310.

10.10.Redis messaging (release / subscription)

Spring Data provides a dedicated messaging integration for Redis, which is similar to JMS integration in Spring Framework in function and naming.

Redis messaging can be roughly divided into two features:

Message release or production

Subscription or consumption of messages

This is a mode example of the generally referred to as a publish / subscription (refermstriction pub / SUB). The RedisTemplate class is used for message generation. Spring Data provides a dedicated message listener container for creating a message-driven POJO (MDP) and the RedisConnection contract for synchronous reception.

exist

Org.springframework.data.redis.connection and org.springframework.data.Redis.Listener packages provide the core features of the REDIS.

10.10.1. Publish (send message)

To publish a message, you can use low-level Redisconnection or advanced redistemplate like other operations. Two entities provide Publish to accept messages and target channels as parameters. Although RedisConnection requires raw data (byte arrays), redistemplate allows arbitrary objects to be incorporated as messages, as shown in the following example:

// send Message Through connection redisconnection con=… BYTE MSG=…

Byte channel=…

Con.Publish (MSG, CHANNEL); // Send Message Through redistemplateredistemplate template=… template.convertandsend ("Hello!", "World");

10.10.2. Subscribe (Receive Message)

At the receiving end, one or more channels can be subscribed by direct naming or using pattern matching. The latter method is very useful because it not only allows you to create multiple subscriptions using a command, but also listen to the channels that have not been created in the subscription (as long as they match the mode).

In the underlying, RedisConnection provides Subscribe and PSUBSCRIBE methods, map the Redis command separately to subscribe by channel or by mode. Note that multiple channels or patterns can be used as parameters. To change the subscription or query it is listening, RedisConnection provides the getSubscription and Issubscribed methods.

Subscription commands in Spring Data Redis are blocked. That is, call Subscribe on the connection will cause the current thread to block when the message is waiting. The thread is released only when the subscription is canceled, which occurs in another thread calling unsubscribe or PUNSUBSCRIBE on the same connection. For solutions for this issue, see "Message Listener Variating" (Back Section of this document).

As mentioned earlier, once the subscription, the connection begins waiting for the message. Only new subscriptions are allowed to modify existing subscriptions and cancel the existing subscription. The call is more than anything else Subscribe, Psubscribe, unsubscribe, or PUNSUBSCRIBE.

In order to subscribe, you need to implement the MessageListener callback. When there is a new message to arrive, callbacks are called and run the user code through the OnMessage method. This interface can not only access the actual message, but also access to the channels it receives and subscribed for matching channels (if any). This information allows the caller to distinguish various messages not only by content, but also check other details.

Message listener container

Due to its obstruction properties, low-level subscription is not attractive because it needs to connect and thread management for each listener. In order to relieve this problem, Spring Data provides

RedisMessagelistenerContainer, which completed all heavy work. If you are familiar with EJB and JMS, you should find that these concepts are familiar because it is designed to support support from Spring Framework and its message-driven POJO (MDP) as close as possible.

RedisMessagelistenerContainer acts as a message listener container. It is used to receive messages from the REDIS channel and drive the MessageListener to inject the instance. The listener container is responsible for all threads received and assigned to the listener for processing. The message listener container is an intermediary between MDP and message providers, responsible for registering receiving messages, resource acquisition, and release, exception conversion, etc. This allows you as an application developer to write (probably complex) business logic associated with the receiving message (and respond to it), and commission the model REDIS infrastructure issue to the framework.

`MessageListener` also enables` subscriptionlistener` to receive notifications when subscribe / cancel subscription confirmation. Synchronous calls are useful.

In addition, in order to minimize the application space,

RedisMessageListenerContainer allows them to share a connection and a thread even if multiple listeners do not share subscriptions. Therefore, regardless of how many listeners or channels are tracked, the cost of running remains unchanged throughout its life cycle. In addition, the container allows runtime configuration changes so that you can add or delete listeners when the application is run without restarting. In addition, the container uses an inert subscription method, and RedisConnection is only used when needed. If all listeners cancel subscription, the cleaning is automatically cleared and the thread is released.

In order to help address the asynchronous features of the message, the container needs one

Java.util.concurrent.executor (or Spring Taskexecutor) to assign a message. Depending on the load, listener’s number or runtime environment, you should change or adjust the executing program to better meet your needs. Especially in the hosted environment (eg, the application server), it is highly recommended to select a suitable tasKexecutor to take advantage of its runtime.

MessagelisteneraDapter

This MessageListeneraDapter class is the last component of Spring asynchronous support messages. In short, it allows you to disclose almost any classes to MDP (although there are some restrictions).

Consider the following interface definition:

public interface MessageDelegate {void handleMessage (String message); void handleMessage (Map message); void handleMessage (byte message); void handleMessage (Serializable message); // pass the channel / pattern as well

Void HandleMessage (Serializable Message, String Channel);

}

Note that although the interface does not expand the MessageListener interface, it can still be used as MDP by using the MessageListeneraDapter class. Also pay attention to how to use a variety of message processing methods to receive and handle different Message types according to strong types of content. In addition, the channel or pattern sent by the message can be transmitted to the method String as a second parameter of Type:

Public class defaultMessageDelegate Implements MessageDelegate {// Implementation Elided for Clarity …}

Note that the above MessageDelegate interface is implemented (the DefaultMessageDelegate class above) does not have Redis dependence. It is indeed a Pojo, we use the following configuration to make it MDP:

XMLns: xsi="http://www.w3.org/2001/xmlschema-instance"

XMLns: redis="http://www.springframework.org/schema/redis"

XSI: SchemAlocation="http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd

Http://www.springframework.org/schema/redis https://www.springframework.org/schema/redis/spring-redis.xsd ">

The listener topic can be channel (for example, Topic="chatroom") or mode (for example, topic="* room")

The above example uses the Redis namespace to declare the message listening container and automatically register POJO as a listener. The complete bean is defined as follows:

Each time you receive a message, the adapter automatically transparently (using the configured redisserializer) low format and the conversion between the desired object type. Any abnormality caused by method calls will be captured and processed by the container (by default, exceptions will be recorded).