Spring Boot 환경에서 Redis를 사용한다면, build.gradle에 다음과 같이 스크립트를 작성 할 것이다.
// Redis 의존성
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
외부 Redis 서버를 사용하는 경우, application.yml에 다음과 같이 Redis 접속 정보를 입력한다.
spring:
redis:
host: localhost
port: 6378
database: 0
password: redispassword
이후 application.yml에 작성된 접속 정보를 바탕으로 Redis 환경설정을 다음과 같이 해준다(임베디드 Redis 서버를 사용하는 경우 아래 설정코드와는 다르게 설정해야한다). 가장 활발하게 운영되고 있는 Lettuce(추천x2)를 사용하여 ConnectionFactory를 만들고 기타 Redis 사용에 필요한 Bean들을 생성해준다.
@Configuration
@EnableRedisRepositories
@Slf4j
public class RedisConfiguration {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.database}")
private int database;
@Value("${spring.redis.password}")
private String password;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
log.info("REDIS HOST: {}", this.host);
log.info("REDIS PORT: {}", this.port);
log.info("REDIS DATABASE: {}", this.database);
log.info("REDIS PASSWORD: {}", this.password);
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(this.host);
redisStandaloneConfiguration.setPort(this.port);
redisStandaloneConfiguration.setDatabase(this.database);
redisStandaloneConfiguration.setPassword(this.password);
return new LettuceConnectionFactory(redisStandaloneConfiguration);
}
@Bean
public RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
return redisTemplate;
}
@Bean
MessageListenerAdapter messageListenerAdapter(RedisMessageSubscriber redisMessageSubscriber) {
return new MessageListenerAdapter(redisMessageSubscriber);
}
@Bean
RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory, MessageListenerAdapter messageListenerAdapter, ChannelTopic topic) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory);
container.addMessageListener(messageListenerAdapter, topic);
return container;
}
@Bean
ChannelTopic topic() {
return new ChannelTopic("topic");
}
}
위 코드를 보면 Redis 서버에서 Publish하고 있는 채널명을 인자로 받는 ChannelTopic Bean을 생성함을 알 수 있다.
이후 Redis에서 Subscribe하고 있는 채널에 온 메시지를 처리하는 MessageAdaptor Bean을 생성하는데, 생성자 인자로 RedisMessageSubscriber 객체를 넘겨주고 있음을 알 수 있다.
@Service
@Slf4j
public class RedisMessageSubscriber implements MessageListener {
@Override
public void onMessage(Message message, byte[] pattern) {
log.info("Message >> {}", message.toString());
}
}
/**
* Listener of messages published in Redis.
*
* @author Costin Leau
* @author Christoph Strobl
*/
public interface MessageListener {
/**
* Callback for processing received objects through Redis.
*
* @param message message must not be {@literal null}.
* @param pattern pattern matching the channel (if specified) - can be {@literal null}.
*/
void onMessage(Message message, @Nullable byte[] pattern);
}
RedisMessageSubscriber는 org.springframework.data.redis.connection 패키지에 있는 MessageListener 인터페이스를 구현한 구현체이다. Message와 pattern을 인자로 받는 onMessage 메소드를 오버라이딩하여 구현하였고, onMessage 메소드에서는 인자로 받은 message 객체의 내용을 문자열로 출력하고 있다.
MessageListener 인터페이스에 명세되어있는 내용을 보면, pattern 인자는 PatterTopic으로 채널을 구독했을 시, 그 패턴 정보를 담고 있음을 알 수 있다.
Message 객체는 org.springframework.data.redis.connection 패키지에 다음과 같이 선언되어있다.
**
* Class encapsulating a Redis message body and its properties.
*
* @author Costin Leau
* @author Christoph Strobl
*/
public interface Message extends Serializable {
/**
* Returns the body (or the payload) of the message.
*
* @return message body. Never {@literal null}.
*/
byte[] getBody();
/**
* Returns the channel associated with the message.
*
* @return message channel. Never {@literal null}.
*/
byte[] getChannel();
}
채널로 전달된 메시지의 본문을 byte형태로 가져올 수 있는 getBody와 채널 정보를 가져올 수 있는 getChannel 메소드가 선언이 되었있다.
이후 다음과 같이 RedisMessageSubscriber를 MessageListenerAdapter의 인자로 넘겨 MessageListenerAdapter Bean을 만들고, MessageListenerContainer에 구독할 ChannelTopic 객체와 함께 등록해준다.
// MessageListenerAdapter는 MessageListenerContainer에서 특정 토픽에 메시지가 온 경우
// 이를 처리하는 클래스이다.
@Bean
MessageListenerAdapter messageListenerAdapter(RedisMessageSubscriber redisMessageSubscriber) {
return new MessageListenerAdapter(redisMessageSubscriber);
}
// MessageListener를 관리하는 Container로 Redis 채널에서 메시지를 받고
// 해당 채널에 등록된 MessageListener에 찾고, 해당 메시지를 주입하는 역할을 수행한다.
@Bean
RedisMessageListenerContainer redisMessageListenerContainer(RedisConnectionFactory redisConnectionFactory, MessageListenerAdapter messageListenerAdapter, ChannelTopic topic) {
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
container.setConnectionFactory(redisConnectionFactory);
container.addMessageListener(messageListenerAdapter, topic);
return container;
}
// Redis에서 구독할 Cahnnel명
@Bean
ChannelTopic topic() {
return new ChannelTopic("topic");
}
위와 같이 설정하고 어플리케이션을 구동하면, Redis의 topic (위 코드의 예시 채널) 채널에 메시지가 publish 된 경우
해당 메시지를 성공적으로 출력할 수 있다.
'Programming > Spring' 카테고리의 다른 글
[Spring Boot] Spring Security with REST API Login AS JSON (8) | 2019.10.23 |
---|---|
[SpringBoot] Redis Channel Subscribe with MessagePack (0) | 2019.09.18 |
[Spring Boot] @Schedule로 스케줄 프로그래밍 하기 (0) | 2019.08.22 |
[SpringBoot] 에러 로그 모니터링 with Sentry (0) | 2019.08.04 |
[SpringBoot] LocalDateTime Json Serialized (2) | 2019.06.19 |