Die Übersetzung des Artikels wurde speziell für Studenten des Kurses "Developer on the Spring Framework" erstellt.
In diesem Artikel werden die Grundlagen der Verwendung von Redis über Spring Boot mithilfe der Spring Data Redis-Bibliothek behandelt.

Wir werden eine Anwendung erstellen, die zeigt, wie CRUD-Operationen über eine Webschnittstelle ausgeführt werden. Der Quellcode für dieses Projekt
ist auf GitHub verfügbar .
Was ist Redis?
Redis ist ein Open Source Data Warehouse für
Schlüsselwertdatenstrukturen , die als Datenbank, Cache und Nachrichtenbroker verwendet werden können. In Bezug auf die Implementierung gehören Schlüsselwertspeicher zu den größten und ältesten Vertretern in der NoSQL-Welt. Redis unterstützt Datenstrukturen wie Zeichenfolgen, Hashes, Listen, Mengen und sortierte Mengen mit Bereichsabfragen.
Das
Spring Data Redis- Framework erleichtert das Schreiben von Spring-Anwendungen, die Redis-Speicher verwenden, und bietet eine bequeme Abstraktion des Datenspeichers.
Redis Server Setup
Der Server steht hier kostenlos zur Verfügung.
Wenn Sie einen Mac verwenden, können Sie ihn mit
homebrew
installieren:
brew install redis
Starten Sie dann den Server:
mikes-MacBook-Air:~ mike$ redis-server 10699:C 23 Nov 08:35:58.306 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 10699:C 23 Nov 08:35:58.307 # Redis version=4.0.2, bits=64, commit=00000000, modified=0, pid=10699, just started 10699:C 23 Nov 08:35:58.307 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf 10699:M 23 Nov 08:35:58.309 * Increased maximum number of open files to 10032 (it was originally set to 256). _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 4.0.2 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 10699 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 10699:M 23 Nov 08:35:58.312 # Server initialized 10699:M 23 Nov 08:35:58.312 * Ready to accept connections
Maven-Abhängigkeiten
pom.xml
wir die erforderlichen Abhängigkeiten in
pom.xml
für die Anwendung, mit der wir arbeiten werden:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
Redis Konfiguration
Wir müssen unsere Anwendung mit dem Redis-Server verbinden. Um eine Verbindung herzustellen, verwenden wir
Jedis , eine Client-Implementierung von Redis.
Konfiguration
Beginnen wir mit der Definition von Konfigurations-Beans:
@Bean JedisConnectionFactory jedisConnectionFactory() { return new JedisConnectionFactory(); } @Bean public RedisTemplate<String, Object> redisTemplate() { final RedisTemplate<String, Object> template = new RedisTemplate<String, Object>(); template.setConnectionFactory(jedisConnectionFactory()); template.setValueSerializer(new GenericToStringSerializer<Object>(Object.class)); return template; }
JedisConnectionFactory
wird als Bean dargestellt, damit wir eine
RedisTemplate
erstellen
RedisTemplate
, um Daten anzufordern.
Post Publisher
Nach den
Prinzipien von SOLID erstellen wir die
MessagePublisher
Schnittstelle:
public interface MessagePublisher { void publish(final String message); }
Wir implementieren die
MessagePublisher
Schnittstelle mithilfe der übergeordneten RedisTemplate, um eine Nachricht zu veröffentlichen, da
RedisTemplate
mit
RedisTemplate
beliebige Objekte als Nachrichten senden können:
@Service public class MessagePublisherImpl implements MessagePublisher { @Autowired private RedisTemplate<String, Object> redisTemplate; @Autowired private ChannelTopic topic; public MessagePublisherImpl() { } public MessagePublisherImpl(final RedisTemplate<String, Object> redisTemplate, final ChannelTopic topic) { this.redisTemplate = redisTemplate; this.topic = topic; } public void publish(final String message) { redisTemplate.convertAndSend(topic.getTopic(), message); } }
Wir definieren dies auch als Bean in
RedisConfig
:
@Bean MessagePublisher redisPublisher() { return new MessagePublisherImpl(redisTemplate(), topic()); }
Nachrichtenempfänger
Um Nachrichten zu abonnieren, müssen Sie die
MessageListener
Schnittstelle implementieren: Jedes Mal, wenn eine neue Nachricht eintrifft, wird der Benutzercode in der
onMessage
Methode
onMessage
. Diese Schnittstelle bietet Zugriff auf die Nachricht, den Kanal, über den sie empfangen wurde, und ermöglicht Ihnen die Verwendung einer beliebigen Vorlage, die zum Abonnieren des Kanals verwendet wird.
@Service public class MessageSubscriber implements MessageListener { public static List<String> messageList = new ArrayList<String>(); public void onMessage(final Message message, final byte[] pattern) { messageList.add(message.toString()); System.out.println("Message received: " + new String(message.getBody())); } }
Außerdem muss diese Klasse in
RedisConfig
als Bean
RedisConfig
:
@Bean MessageListenerAdapter messageListener() { return new MessageListenerAdapter(new MessageSubscriber()); }
Redisrepository
Nachdem wir die Anwendung für die Interaktion mit dem Redis-Server eingerichtet haben, bereiten wir die Anwendung für den Empfang von Testdaten vor.
Modell
In diesem Beispiel definieren wir ein
Movie
mit zwei Feldern:
private String id; private String name;
Repository-Schnittstelle
Im Gegensatz zu anderen Spring Data-Projekten bietet Spring Data Redis alles, was Sie für die Arbeit mit anderen Spring Data-Schnittstellen benötigen. Dies mag für Personen mit Erfahrung mit anderen Spring Data-Projekten seltsam aussehen.
Oft ist es nicht erforderlich, eine Implementierung der Repository-Schnittstelle für Spring Data-Projekte zu schreiben. Wir interagieren nur mit der Schnittstelle. Spring Data JPA bietet zahlreiche Repository-Schnittstellen, die erweitert werden können, um Funktionen wie CRUD-Operationen, abgeleitete Abfragen und Paginierung bereitzustellen.
Leider müssen wir
unsere eigene Schnittstelle schreiben und dann die Methoden definieren :
public interface RedisRepository { Map<Object, Object> findAllMovies(); void add(Movie movie); void delete(String id); Movie findMovie(String id); }
Repository-Implementierung
Die Klasse verwendet
redisTemplate
das in der
RedisConfig
Konfigurationsklasse definiert ist.
Wir verwenden
HashOperations
, die Spring Data Redis anbietet:
@Repository public class RedisRepositoryImpl implements RedisRepository { private static final String KEY = "Movie"; private RedisTemplate<String, Object> redisTemplate; private HashOperations hashOperations; @Autowired public RedisRepositoryImpl(RedisTemplate<String, Object> redisTemplate){ this.redisTemplate = redisTemplate; } @PostConstruct private void init(){ hashOperations = redisTemplate.opsForHash(); } public void add(final Movie movie) { hashOperations.put(KEY, movie.getId(), movie.getName()); } public void delete(final String id) { hashOperations.delete(KEY, id); } public Movie findMovie(final String id){ return (Movie) hashOperations.get(KEY, id); } public Map<Object, Object> findAllMovies(){ return hashOperations.entries(KEY); } }
Achten wir auf die Methode
init()
. In dieser Methode verwenden wir eine Funktion namens
opsForHash()
, die Operationen zurückgibt, die mit Hash-Werten ausgeführt werden,
opsForHash()
diesem Schlüssel zugeordnet sind. Dann verwenden wir für alle unsere CRUD-Operationen
hashOps
, das in
init()
definiert wurde.
Webschnittstelle
In diesem Abschnitt werden wir uns mit dem Hinzufügen von Redis CRUD-Funktionen zur Weboberfläche befassen.
Hinzufügen eines Films
Wir möchten einen Film über eine Webseite hinzufügen können. Der Schlüssel ist die Kennung des Films und der Wert ist das eigentliche Objekt. Wir werden jedoch später darauf zurückkommen, sodass nur der Name des Films als Wert angezeigt wird.
Fügen wir dem HTML-Dokument ein Formular hinzu und weisen Sie die entsprechenden Namen und Bezeichner zu:
<form id="addForm"> <div class="form-group"> <label for="keyInput">Movie ID (key)</label> <input name="keyInput" id="keyInput" class="form-control"/> </div> <div class="form-group"> <label for="valueInput">Movie Name (field of Movie object value)</label> <input name="valueInput" id="valueInput" class="form-control"/> </div> <button class="btn btn-default" id="addButton">Add</button> </form>
Jetzt verwenden wir JavaScript, um Werte beim Senden des Formulars zu speichern:
$(document).ready(function() { var keyInput = $('#keyInput'), valueInput = $('#valueInput'); refreshTable(); $('#addForm').on('submit', function(event) { var data = { key: keyInput.val(), value: valueInput.val() }; $.post('/add', data, function() { refreshTable(); keyInput.val(''); valueInput.val(''); keyInput.focus(); }); event.preventDefault(); }); keyInput.focus(); });
Wir legen
@RequestMapping
Parameter für die POST-Anforderung fest, fordern den Schlüssel und den Wert an, erstellen ein
Movie
Objekt und speichern es im Repository:
@RequestMapping(value = "/add", method = RequestMethod.POST) public ResponseEntity<String> add( @RequestParam String key, @RequestParam String value) { Movie movie = new Movie(key, value); redisRepository.add(movie); return new ResponseEntity<>(HttpStatus.OK); }
Inhalt anzeigen
Sobald das Movie-Objekt hinzugefügt wurde, aktualisieren wir die Tabelle, um die neuen Werte anzuzeigen. Im Block des JavaScript-Codes haben wir die Funktion
refreshTable()
aufgerufen. Es führt eine GET-Anforderung aus, um die aktuellen Daten im Repository abzurufen:
function refreshTable() { $.get('/values', function(data) { var attr, mainTable = $('#mainTable tbody'); mainTable.empty(); for (attr in data) { if (data.hasOwnProperty(attr)) { mainTable.append(row(attr, data[attr])); } } }); }
Die GET-Anforderung wird von der
findAll()
-Methode verarbeitet, die alle im Speicher gespeicherten Movie-Objekte abruft und dann den Datentyp von
Map <Object, Object>
in
Map <String, String>
konvertiert:
@RequestMapping("/values") public @ResponseBody Map<String, String> findAll() { Map<Object, Object> aa = redisRepository.findAllMovies(); Map<String, String> map = new HashMap<String, String>(); for(Map.Entry<Object, Object> entry : aa.entrySet()){ String key = (String) entry.getKey(); map.put(key, aa.get(key).toString()); } return map; }
Filmentfernung
Wir werden ein Skript schreiben, um eine POST-Anforderung entlang des
/delete
Pfads auszuführen, die Tabelle zu aktualisieren und den Tastaturfokus für eine bequeme Eingabe zu wechseln:
function deleteKey(key) { $.post('/delete', {key: key}, function() { refreshTable(); $('#keyInput').focus(); }); }
Wir fordern einen Schlüssel an und löschen das Objekt in
redisRepository
basierend auf diesem Schlüssel:
@RequestMapping(value = "/delete", method = RequestMethod.POST) public ResponseEntity<String> delete(@RequestParam String key) { redisRepository.delete(key); return new ResponseEntity<>(HttpStatus.OK); }
Demo
Hier haben wir zwei Filme hinzugefügt:

Und ein Film wurde gelöscht:

Fazit
In diesem Handbuch haben wir uns Spring Data Redis und eine Möglichkeit angesehen, es mit einer Webanwendung zu verbinden, um CRUD-Operationen auszuführen.
Der Quellcode für die Beispielanwendung befindet sich auf
GitHub .
Das ist alles. Traditionell auf Ihre Kommentare warten.