A tradução do artigo foi preparada especificamente para os alunos do curso "Developer on the Spring Framework".
Neste artigo, abordaremos o básico do uso do Redis através do Spring Boot usando a biblioteca Spring Data Redis.

Criaremos um aplicativo que demonstre como executar operações CRUD por meio de uma interface da web. O código fonte deste projeto
está disponível no GitHub .
O que é Redis?
O Redis é um data warehouse de código aberto para estruturas de dados de
valor-chave que podem ser usados como banco de dados, cache e intermediário de mensagens. Em termos de implementação, os armazenamentos de valores-chave estão entre os maiores e mais antigos representantes do mundo NoSQL. O Redis suporta estruturas de dados como strings, hashes, listas, conjuntos e conjuntos classificados com consultas de intervalo.
A estrutura
Spring Data Redis facilita a gravação de aplicativos Spring que usam armazenamento Redis, fornecendo uma abstração conveniente do armazenamento de dados.
Configuração do servidor Redis
O servidor está disponível gratuitamente
aqui .
Se você estiver usando um Mac, poderá instalá-lo usando o
homebrew
:
brew install redis
Em seguida, inicie o servidor:
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
Dependências do Maven
Vamos declarar as dependências necessárias no
pom.xml
para o aplicativo com o qual trabalharemos:
<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>
Configuração Redis
Precisamos conectar nosso aplicativo ao servidor Redis. Para estabelecer uma conexão, usamos o
Jedis , uma implementação cliente do Redis.
Configuração
Vamos começar com a definição de beans de configuração:
@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
é apresentado como um bean, para que possamos criar um
RedisTemplate
para solicitar dados.
Publicar editor
Seguindo os
princípios do SOLID , criamos a interface
MessagePublisher
:
public interface MessagePublisher { void publish(final String message); }
Implementamos a interface
MessagePublisher
usando o RedisTemplate de alto nível para publicar uma mensagem, pois o
RedisTemplate
permite enviar objetos arbitrários como mensagens:
@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); } }
Também definimos isso como um bean no
RedisConfig
:
@Bean MessagePublisher redisPublisher() { return new MessagePublisherImpl(redisTemplate(), topic()); }
Destinatário da mensagem
Para assinar mensagens, é necessário implementar a interface
MessageListener
: sempre que uma nova mensagem chega, o código do usuário localizado no método
onMessage
é
onMessage
. Essa interface fornece acesso à mensagem, ao canal pelo qual foi recebida, e permite que você use qualquer modelo usado para se inscrever no canal.
@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())); } }
Além disso, essa classe deve ser registrada como um bean no
RedisConfig
:
@Bean MessageListenerAdapter messageListener() { return new MessageListenerAdapter(new MessageSubscriber()); }
Redisrepositório
Agora que configuramos o aplicativo para interagir com o servidor Redis, prepararemos o aplicativo para receber dados de teste.
Modelo
Neste exemplo, definimos um modelo de
Movie
com dois campos:
private String id; private String name;
Interface do Repositório
Ao contrário de outros projetos do Spring Data, o Spring Data Redis fornece tudo o que você precisa para trabalhar em cima de outras interfaces do Spring Data. Isso pode parecer estranho para pessoas com experiência em outros projetos do Spring Data.
Geralmente, não há necessidade de escrever uma implementação de interface de repositório com projetos do Spring Data. Nós apenas interagimos com a interface. O Spring Data JPA fornece inúmeras interfaces de repositório que podem ser estendidas para fornecer recursos como operações CRUD, consultas derivadas e paginação.
Infelizmente, precisamos
escrever nossa própria interface e depois definir os métodos :
public interface RedisRepository { Map<Object, Object> findAllMovies(); void add(Movie movie); void delete(String id); Movie findMovie(String id); }
Implementação de Repositório
A classe usa
redisTemplate
definido na
RedisConfig
configuração
RedisConfig
.
Usamos o
HashOperations
, que o Spring Data Redis oferece:
@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); } }
Vamos prestar atenção ao método
init()
. Neste método, usamos uma função chamada
opsForHash()
, que retorna operações executadas com valores de hash
opsForHash()
a essa chave. Em seguida, usamos o
hashOps
, definido em
init()
, para todas as nossas operações CRUD.
Interface da web
Nesta seção, veremos como adicionar recursos Redis CRUD à interface da web.
Adicionando um filme
Queremos poder adicionar um filme através de uma página da web. A chave é o identificador do filme e o valor é o objeto real. No entanto, retornaremos a isso mais tarde, portanto, apenas o nome do filme será exibido como o valor.
Vamos adicionar um formulário ao documento HTML e atribuir os nomes e identificadores apropriados:
<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>
Agora usamos JavaScript para salvar valores ao enviar o formulário:
$(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(); });
@RequestMapping
parâmetros
@RequestMapping
para a solicitação POST, solicitamos a chave e o valor, criamos um objeto
Movie
e salvamos no repositório:
@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); }
Exibir conteúdo
Depois que o objeto Movie é adicionado, atualizamos a tabela para exibir os novos valores. No bloco de código JavaScript, chamamos a função
refreshTable()
. Ele executa uma solicitação GET para obter os dados atuais no repositório:
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])); } } }); }
A solicitação GET é processada pelo método
findAll()
, que recupera todos os objetos Movie armazenados na loja e converte o tipo de dados de
Map <Object, Object>
para
Map <String, String>
:
@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; }
Remoção de filme
Escreveremos um script para executar uma solicitação POST no caminho
/delete
, atualizar a tabela e alternar o foco do teclado para uma entrada conveniente:
function deleteKey(key) { $.post('/delete', {key: key}, function() { refreshTable(); $('#keyInput').focus(); }); }
Solicitamos uma chave e
redisRepository
o objeto em
redisRepository
base nesta chave:
@RequestMapping(value = "/delete", method = RequestMethod.POST) public ResponseEntity<String> delete(@RequestParam String key) { redisRepository.delete(key); return new ResponseEntity<>(HttpStatus.OK); }
Demo
Aqui nós adicionamos dois filmes:

E um filme foi excluído:

Conclusão
Neste guia, analisamos o Spring Data Redis e uma maneira de conectá-lo a um aplicativo Web para executar operações CRUD.
O código fonte do aplicativo de amostra está no
GitHub .
Só isso. Tradicionalmente, aguardando seus comentários.