├── image
├── redis-create.png
└── redis-project.png
├── redis-crud
├── src
│ └── main
│ │ ├── resources
│ │ ├── application.properties
│ │ └── logback-spring.xml
│ │ └── java
│ │ └── com
│ │ └── villainscode
│ │ └── redis
│ │ ├── RedisCrudApplication.java
│ │ ├── message
│ │ ├── RedisSubscriber.java
│ │ ├── RedisPublisher.java
│ │ └── MessageController.java
│ │ ├── config
│ │ └── RedisConfig.java
│ │ ├── keygenerate
│ │ └── KeyGenerateService.java
│ │ └── rediskey
│ │ ├── RedisKeyController.java
│ │ └── RedisKeyService.java
└── build.gradle
├── redis-sub
├── src
│ └── main
│ │ ├── resources
│ │ └── application.properties
│ │ └── java
│ │ └── com
│ │ └── villainscode
│ │ └── redis
│ │ ├── RedisSubApplication.java
│ │ ├── subscriber
│ │ ├── OrderDTO.java
│ │ └── SubscriberEventListener.java
│ │ └── config
│ │ ├── RedisConfiguration.java
│ │ └── SubscriberConfiguration.java
└── build.gradle
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── settings.gradle
├── redis-pub
├── src
│ └── main
│ │ ├── resources
│ │ └── application.properties
│ │ └── java
│ │ └── com
│ │ └── villainscode
│ │ └── redis
│ │ ├── RedisPubApplication.java
│ │ ├── model
│ │ └── OrderQueue.java
│ │ ├── publisher
│ │ ├── RedisPublisher.java
│ │ ├── PublisherController.java
│ │ └── OrderService.java
│ │ └── config
│ │ └── RedisConfiguration.java
└── build.gradle
├── .idea
├── vcs.xml
├── .gitignore
├── inspectionProfiles
│ └── Project_Default.xml
├── misc.xml
├── gradle.xml
└── uiDesigner.xml
├── redis-sample
├── build.gradle
└── src
│ └── main
│ ├── resources
│ └── logback-spring.xml
│ └── java
│ ├── message
│ └── Receiver.java
│ └── com
│ └── villainscode
│ └── redis
│ └── SpringRedisApplication.java
├── .gitignore
├── gradlew.bat
├── gradlew
└── readme.md
/image/redis-create.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/villainscode/Spring-Redis/HEAD/image/redis-create.png
--------------------------------------------------------------------------------
/image/redis-project.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/villainscode/Spring-Redis/HEAD/image/redis-project.png
--------------------------------------------------------------------------------
/redis-crud/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=8080
2 |
3 | spring.data.redis.url=redis://localhost:6379
--------------------------------------------------------------------------------
/redis-sub/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=8082
2 |
3 | spring.data.redis.url=redis://localhost:6379
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/villainscode/Spring-Redis/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | rootProject.name = 'Spring-Redis'
2 | include 'redis-sample'
3 | include 'redis-crud'
4 | include 'redis-pub'
5 | include 'redis-sub'
6 |
7 |
--------------------------------------------------------------------------------
/redis-pub/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | server.port=8081
2 |
3 | spring.data.redis.url=redis://localhost:6379
4 |
5 | redis.publisher.topic=order-q
6 | stream.key=order-id
7 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 | # Datasource local storage ignored files
7 | /dataSources/
8 | /dataSources.local.xml
9 |
--------------------------------------------------------------------------------
/redis-sample/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | }
4 |
5 | group = 'com.villainscode.redis'
6 | version = '0.0.1-SNAPSHOT'
7 |
8 | repositories {
9 | mavenCentral()
10 | }
11 |
12 | dependencies {
13 |
14 | }
15 |
16 | test {
17 | useJUnitPlatform()
18 | }
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Wed Jul 10 13:37:39 KST 2024
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
5 | zipStoreBase=GRADLE_USER_HOME
6 | zipStorePath=wrapper/dists
7 |
--------------------------------------------------------------------------------
/.idea/inspectionProfiles/Project_Default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/redis-crud/src/main/resources/logback-spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %d{yyyy-MM-dd HH:mm:ss} - %msg%n
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/redis-sample/src/main/resources/logback-spring.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | %d{yyyy-MM-dd HH:mm:ss} - %msg%n
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/redis-crud/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | }
4 |
5 |
6 | group = 'com.villainscode'
7 | version = '0.0.1-SNAPSHOT'
8 |
9 | repositories {
10 | mavenCentral()
11 | }
12 |
13 | dependencies {
14 | implementation 'org.springframework.boot:spring-boot-starter-web'
15 | //implementation group: 'org.hibernate.validator', name: 'hibernate-validator', version: '7.0.5.Final'
16 | }
17 |
18 | test {
19 | useJUnitPlatform()
20 | }
--------------------------------------------------------------------------------
/redis-crud/src/main/java/com/villainscode/redis/RedisCrudApplication.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | @SpringBootApplication
7 | public class RedisCrudApplication {
8 |
9 | public static void main(String[] args) {
10 | SpringApplication.run(RedisCrudApplication.class, args);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/redis-pub/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | }
4 |
5 |
6 | group = 'com.villainscode'
7 | version = '0.0.1-SNAPSHOT'
8 |
9 | repositories {
10 | mavenCentral()
11 | }
12 |
13 | dependencies {
14 | implementation 'org.springframework.boot:spring-boot-starter-web'
15 | //implementation group: 'org.hibernate.validator', name: 'hibernate-validator', version: '7.0.5.Final'
16 | }
17 |
18 | test {
19 | useJUnitPlatform()
20 | }
--------------------------------------------------------------------------------
/redis-sub/build.gradle:
--------------------------------------------------------------------------------
1 | plugins {
2 | id 'java'
3 | }
4 |
5 |
6 | group = 'com.villainscode'
7 | version = '0.0.1-SNAPSHOT'
8 |
9 | repositories {
10 | mavenCentral()
11 | }
12 |
13 | dependencies {
14 | implementation 'org.springframework.boot:spring-boot-starter-web'
15 | //implementation group: 'org.hibernate.validator', name: 'hibernate-validator', version: '7.0.5.Final'
16 | }
17 |
18 | test {
19 | useJUnitPlatform()
20 | }
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/redis-pub/src/main/java/com/villainscode/redis/RedisPubApplication.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | /**
7 | * @author CodeVillains
8 | * @description :
9 | */
10 | @SpringBootApplication
11 | public class RedisPubApplication {
12 |
13 | public static void main(String[] args) {
14 | SpringApplication.run(RedisPubApplication.class, args);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/redis-sub/src/main/java/com/villainscode/redis/RedisSubApplication.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | /**
7 | * @author CodeVillains
8 | * @description :
9 | */
10 | @SpringBootApplication
11 | public class RedisSubApplication {
12 |
13 | public static void main(String[] args) {
14 | SpringApplication.run(RedisSubApplication.class, args);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/redis-pub/src/main/java/com/villainscode/redis/model/OrderQueue.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.model;
2 |
3 | import java.io.Serializable;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | @Data
10 | @NoArgsConstructor
11 | @AllArgsConstructor
12 | @Builder
13 | public class OrderQueue implements Serializable {
14 |
15 | private String id;
16 | private String userId;
17 | private String productName;
18 | private int price;
19 | private int qty;
20 | }
--------------------------------------------------------------------------------
/redis-sub/src/main/java/com/villainscode/redis/subscriber/OrderDTO.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.subscriber;
2 |
3 | import java.io.Serializable;
4 | import lombok.AllArgsConstructor;
5 | import lombok.Builder;
6 | import lombok.Data;
7 | import lombok.NoArgsConstructor;
8 |
9 | @Data
10 | @NoArgsConstructor
11 | @AllArgsConstructor
12 | @Builder
13 | public class OrderDTO implements Serializable {
14 |
15 |
16 | private String id;
17 | private String userId;
18 | private String productName;
19 | private int price;
20 | private int qty;
21 | }
--------------------------------------------------------------------------------
/redis-sample/src/main/java/message/Receiver.java:
--------------------------------------------------------------------------------
1 | package message;
2 |
3 | import java.util.concurrent.atomic.AtomicInteger;
4 | import org.slf4j.Logger;
5 | import org.slf4j.LoggerFactory;
6 |
7 | /**
8 | * @author CodeVillains description :
9 | */
10 | public class Receiver {
11 | private static final Logger LOGGER = LoggerFactory.getLogger(Receiver.class);
12 |
13 | private AtomicInteger count = new AtomicInteger();
14 |
15 | public void receiveMessage(String message) {
16 | LOGGER.info("Received <" + message + ">");
17 | count.incrementAndGet();
18 | }
19 |
20 | public int getCount() {
21 | return count.get();
22 | }
23 |
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .gradle
2 |
3 |
4 | build/
5 | !gradle/wrapper/gradle-wrapper.jar
6 | !**/src/main/**/build/
7 | !**/src/test/**/build/
8 |
9 | ### IntelliJ IDEA ###
10 | .idea/modules.xml
11 | .idea/jarRepositories.xml
12 | .idea/compiler.xml
13 | .idea/libraries/
14 | *.iws
15 | *.iml
16 | *.ipr
17 | out/
18 | !**/src/main/**/out/
19 | !**/src/test/**/out/
20 |
21 | ### Eclipse ###
22 | .apt_generated
23 | .classpath
24 | .factorypath
25 | .project
26 | .settings
27 | .springBeans
28 | .sts4-cache
29 | bin/
30 | !**/src/main/**/bin/
31 | !**/src/test/**/bin/
32 |
33 | ### NetBeans ###
34 | /nbproject/private/
35 | /nbbuild/
36 | /dist/
37 | /nbdist/
38 | /.nb-gradle/
39 |
40 | ### VS Code ###
41 | .vscode/
42 |
43 | ### Mac OS ###
44 | .DS_Store
--------------------------------------------------------------------------------
/redis-pub/src/main/java/com/villainscode/redis/publisher/RedisPublisher.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.publisher;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.beans.factory.annotation.Value;
5 | import org.springframework.context.annotation.Bean;
6 | import org.springframework.context.annotation.Configuration;
7 | import org.springframework.data.redis.listener.ChannelTopic;
8 |
9 | /**
10 | * @author CodeVillains
11 | * @description :
12 | */
13 | @Slf4j
14 | @Configuration
15 | public class RedisPublisher {
16 | @Value("${redis.publisher.topic}")
17 | private String topic;
18 |
19 | @Bean
20 | public ChannelTopic topic() {
21 | log.info("# topic = {}", topic);
22 | return new ChannelTopic(topic);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
20 |
21 |
--------------------------------------------------------------------------------
/redis-pub/src/main/java/com/villainscode/redis/publisher/PublisherController.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.publisher;
2 |
3 |
4 | import com.villainscode.redis.model.OrderQueue;
5 | import org.springframework.web.bind.annotation.PostMapping;
6 | import org.springframework.web.bind.annotation.RequestBody;
7 | import org.springframework.web.bind.annotation.RestController;
8 |
9 | /**
10 | * @author CodeVillains
11 | * @description :
12 | */
13 | @RestController
14 | public class PublisherController {
15 | private final OrderService orderService;
16 |
17 | public PublisherController(OrderService orderService) {
18 | this.orderService = orderService;
19 | }
20 |
21 | @PostMapping("/publish")
22 | public String publish(@RequestBody OrderQueue orderQueue) {
23 | orderService.publish(orderQueue);
24 | return "Success";
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/redis-pub/src/main/java/com/villainscode/redis/config/RedisConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.data.redis.connection.RedisConnectionFactory;
6 | import org.springframework.data.redis.core.RedisTemplate;
7 | import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
8 |
9 | @Configuration
10 | public class RedisConfiguration {
11 |
12 | @Bean(name = "publisherRedisTemplate")
13 | public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
14 |
15 | RedisTemplate template = new RedisTemplate<>();
16 | template.setConnectionFactory(connectionFactory);
17 | template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
18 | return template;
19 | }
20 | }
--------------------------------------------------------------------------------
/redis-crud/src/main/java/com/villainscode/redis/message/RedisSubscriber.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.message;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.data.redis.connection.Message;
5 | import org.springframework.data.redis.connection.MessageListener;
6 | import org.springframework.stereotype.Service;
7 |
8 | /**
9 | * @author CodeVillains
10 | * @description :
11 | */
12 | @Slf4j
13 | @Service
14 | public class RedisSubscriber implements MessageListener {
15 |
16 | @Override
17 | public void onMessage(Message message, byte[] pattern) {
18 | String receiveMessage = new String(message.getBody());
19 | String channel = new String(message.getChannel());
20 |
21 | log.info("Received message '{}' from channel '{}'", message, channel);
22 | if ("myChannel".equals(channel)) {
23 | log.info("Received message from 'myChannel': {}", message);
24 | // Add assertions or additional actions based on the received message
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/redis-pub/src/main/java/com/villainscode/redis/publisher/OrderService.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.publisher;
2 |
3 | import com.villainscode.redis.model.OrderQueue;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.beans.factory.annotation.Autowired;
6 | import org.springframework.beans.factory.annotation.Qualifier;
7 | import org.springframework.data.redis.core.RedisTemplate;
8 | import org.springframework.data.redis.listener.ChannelTopic;
9 | import org.springframework.stereotype.Service;
10 |
11 | /**
12 | * @author CodeVillains
13 | * @description :
14 | */
15 | @Slf4j
16 | @Service
17 | public class OrderService {
18 |
19 | @Autowired
20 | @Qualifier("publisherRedisTemplate")
21 | private RedisTemplate redisTemplate;
22 |
23 | @Autowired
24 | private ChannelTopic channelTopic;
25 |
26 | public Long publish(OrderQueue orderQueue) {
27 | log.info("# publish order queue = {}", orderQueue);
28 | return redisTemplate.convertAndSend(channelTopic.getTopic(), orderQueue);
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/redis-crud/src/main/java/com/villainscode/redis/config/RedisConfig.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.config;
2 |
3 | import java.util.Arrays;
4 | import java.util.Objects;
5 | import lombok.extern.slf4j.Slf4j;
6 | import org.springframework.cache.annotation.CachingConfigurerSupport;
7 | import org.springframework.cache.annotation.EnableCaching;
8 | import org.springframework.cache.interceptor.KeyGenerator;
9 | import org.springframework.context.annotation.Bean;
10 | import org.springframework.context.annotation.Configuration;
11 |
12 | // 환경 설정, 캐싱 활성화
13 | @Slf4j
14 | @Configuration
15 | @EnableCaching
16 | public class RedisConfig extends CachingConfigurerSupport {
17 |
18 | /**
19 | * 캐시 키 생성 정의
20 | * @return
21 | */
22 | @Bean
23 | public KeyGenerator keyGenerator() {
24 | return (target, method, params) -> {
25 | StringBuilder key = new StringBuilder();
26 | key.append(target.getClass().getName()).append("-");
27 | key.append(method.getName()).append("-");
28 | key.append(Arrays.toString(params));
29 |
30 | return Objects.hash(key.toString());
31 | };
32 | }
33 | }
--------------------------------------------------------------------------------
/redis-crud/src/main/java/com/villainscode/redis/message/RedisPublisher.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.message;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.data.redis.core.StringRedisTemplate;
5 | import org.springframework.stereotype.Service;
6 |
7 | /**
8 | * @author CodeVillains
9 | * @description :
10 | */
11 | @Slf4j
12 | @Service
13 | public class RedisPublisher {
14 |
15 | private final StringRedisTemplate stringRedisTemplate;
16 |
17 | public RedisPublisher(StringRedisTemplate stringRedisTemplate) {
18 | this.stringRedisTemplate = stringRedisTemplate;
19 | }
20 |
21 | public void sendMessage(String channel, String message) {
22 | log.info("# channel = {}, message = {}", channel, message);
23 | try {
24 | stringRedisTemplate.convertAndSend(channel, message);
25 | log.info("Message sent successfully to channel '{}'", channel);
26 | } catch (Exception e) {
27 | log.error("Failed to send message to channel '{}': {}", channel, e.getMessage());
28 | e.printStackTrace(); // Handle or log the exception appropriately
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/redis-sub/src/main/java/com/villainscode/redis/config/RedisConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.config;
2 |
3 | import org.springframework.beans.factory.annotation.Value;
4 | import org.springframework.context.annotation.Bean;
5 | import org.springframework.context.annotation.Configuration;
6 | import org.springframework.data.redis.connection.RedisConnectionFactory;
7 | import org.springframework.data.redis.core.RedisTemplate;
8 | import org.springframework.data.redis.listener.ChannelTopic;
9 | import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
10 |
11 | /**
12 | * @author CodeVillains
13 | * @description :
14 | */
15 | @Configuration
16 | public class RedisConfiguration {
17 |
18 | @Value(value = "${redis.publisher.topic:order-q}")
19 | private String topic;
20 |
21 | @Bean
22 | public ChannelTopic topic() {
23 | return new ChannelTopic(topic);
24 | }
25 |
26 | @Bean(name = "subscriberRedisTemplate")
27 | public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
28 | RedisTemplate template = new RedisTemplate<>();
29 | template.setConnectionFactory(redisConnectionFactory);
30 | template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
31 | return template;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/redis-sub/src/main/java/com/villainscode/redis/config/SubscriberConfiguration.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.config;
2 |
3 | import org.springframework.context.annotation.Bean;
4 | import org.springframework.context.annotation.Configuration;
5 | import org.springframework.data.redis.connection.MessageListener;
6 | import org.springframework.data.redis.connection.RedisConnectionFactory;
7 | import org.springframework.data.redis.listener.ChannelTopic;
8 | import org.springframework.data.redis.listener.RedisMessageListenerContainer;
9 |
10 | /**
11 | * @author CodeVillains
12 | * @description :
13 | */
14 | @Configuration
15 | public class SubscriberConfiguration {
16 |
17 | private final MessageListener messageListener;
18 | private final RedisConnectionFactory redisConnectionFactory;
19 |
20 | public SubscriberConfiguration(MessageListener messageListener, RedisConnectionFactory redisConnectionFactory) {
21 | this.messageListener = messageListener;
22 | this.redisConnectionFactory = redisConnectionFactory;
23 | }
24 |
25 | @Bean
26 | public RedisMessageListenerContainer redisMessageListenerContainer(ChannelTopic topic) {
27 | RedisMessageListenerContainer container = new RedisMessageListenerContainer();
28 | container.setConnectionFactory(redisConnectionFactory);
29 | container.addMessageListener(messageListener, topic);
30 | return container;
31 | }
32 | }
33 |
34 |
--------------------------------------------------------------------------------
/redis-crud/src/main/java/com/villainscode/redis/keygenerate/KeyGenerateService.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.keygenerate;
2 |
3 | import java.lang.reflect.Method;
4 | import lombok.extern.slf4j.Slf4j;
5 | import org.springframework.cache.interceptor.KeyGenerator;
6 | import org.springframework.stereotype.Service;
7 |
8 | /**
9 | * @author CodeVillains
10 | * @description :
11 | */
12 | @Slf4j
13 | @Service
14 | public class KeyGenerateService {
15 | private final KeyGenerator keyGenerator;
16 |
17 | public KeyGenerateService(KeyGenerator keyGenerator) {
18 | this.keyGenerator = keyGenerator;
19 | }
20 |
21 | public void setKeyGenerator(Integer number, String value) throws NoSuchMethodException {
22 | // RedisConfig에서 정의한 KeyGenerator를 사용하여 키 생성
23 | Object generatedKey = keyGenerator.generate(this, getClass().getDeclaredMethod("setKeyGenerator", Integer.class, String.class), number, value);
24 | // 생성된 키를 Redis 또는 다른 용도로 사용
25 | log.info("Generated Redis Key : {}" + generatedKey);
26 | }
27 |
28 | public String generateKey(Integer number, String value) throws NoSuchMethodException {
29 | Method method = getClass().getDeclaredMethod("setKeyGenerator", Integer.class, String.class);
30 | Object generatedKey = keyGenerator.generate(this, method, number, value);
31 | log.info("# generatedKey = {}", generatedKey);
32 | return generatedKey.toString();
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/redis-crud/src/main/java/com/villainscode/redis/message/MessageController.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.message;
2 |
3 | import lombok.extern.slf4j.Slf4j;
4 | import org.springframework.http.ResponseEntity;
5 | import org.springframework.web.bind.annotation.PathVariable;
6 | import org.springframework.web.bind.annotation.PostMapping;
7 | import org.springframework.web.bind.annotation.RequestBody;
8 | import org.springframework.web.bind.annotation.RequestMapping;
9 | import org.springframework.web.bind.annotation.RestController;
10 |
11 | /**
12 | * @author CodeVillains
13 | * @description : test.http
14 | * POST http://localhost:8080/message/testChannel
15 | * Content-Type: application/json
16 | *
17 | * {
18 | * "message": "Hello, this is a test message."
19 | * }
20 | */
21 | @Slf4j
22 | @RestController
23 | @RequestMapping("/message")
24 | public class MessageController {
25 |
26 | private final RedisPublisher redisPublisher;
27 |
28 | public MessageController(RedisPublisher redisPublisher) {
29 | this.redisPublisher = redisPublisher;
30 | }
31 |
32 | @PostMapping("/{channel}")
33 | public ResponseEntity sendMessage(@PathVariable String channel, @RequestBody String message) {
34 | log.info("channel = {}, {}", channel, message);
35 | redisPublisher.sendMessage(channel, message);
36 | return ResponseEntity.ok("message send to chnanel : " + channel + " and message : " + message);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/redis-sub/src/main/java/com/villainscode/redis/subscriber/SubscriberEventListener.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.subscriber;
2 |
3 | import com.fasterxml.jackson.core.exc.StreamReadException;
4 | import com.fasterxml.jackson.databind.DatabindException;
5 | import com.fasterxml.jackson.databind.ObjectMapper;
6 | import java.io.IOException;
7 | import lombok.extern.slf4j.Slf4j;
8 | import org.springframework.beans.factory.annotation.Autowired;
9 | import org.springframework.beans.factory.annotation.Qualifier;
10 | import org.springframework.data.redis.connection.Message;
11 | import org.springframework.data.redis.connection.MessageListener;
12 | import org.springframework.data.redis.core.RedisTemplate;
13 | import org.springframework.stereotype.Service;
14 |
15 | /**
16 | * @author CodeVillains
17 | * @description :
18 | */
19 | @Slf4j
20 | @Service
21 | public class SubscriberEventListener implements MessageListener {
22 |
23 | @Autowired
24 | private ObjectMapper objectMapper;
25 |
26 | @Autowired
27 | @Qualifier("subscriberRedisTemplate")
28 | private RedisTemplate redisTemplate;
29 |
30 | @Override
31 | public void onMessage(Message message, byte[] pattern) {
32 | try {
33 | log.info("# new message received = {}", message);
34 | OrderDTO orderDTO = objectMapper.readValue(message.getBody(), OrderDTO.class);
35 | } catch (IOException e) {
36 | log.error("# Subscriber Event Error = {}", message);
37 | throw new RuntimeException(e);
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/redis-sample/src/main/java/com/villainscode/redis/SpringRedisApplication.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis;
2 |
3 |
4 | import message.Receiver;
5 | import org.slf4j.Logger;
6 | import org.slf4j.LoggerFactory;
7 | import org.springframework.boot.SpringApplication;
8 | import org.springframework.boot.autoconfigure.SpringBootApplication;
9 | import org.springframework.context.ApplicationContext;
10 | import org.springframework.context.annotation.Bean;
11 | import org.springframework.data.redis.connection.RedisConnectionFactory;
12 | import org.springframework.data.redis.core.StringRedisTemplate;
13 | import org.springframework.data.redis.listener.PatternTopic;
14 | import org.springframework.data.redis.listener.RedisMessageListenerContainer;
15 | import org.springframework.data.redis.listener.adapter.MessageListenerAdapter;
16 |
17 | @SpringBootApplication
18 | public class SpringRedisApplication {
19 |
20 | private static final Logger LOGGER = LoggerFactory.getLogger(SpringRedisApplication.class);
21 |
22 | @Bean
23 | RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
24 | RedisMessageListenerContainer container = new RedisMessageListenerContainer();
25 | container.setConnectionFactory(connectionFactory);
26 | container.addMessageListener(listenerAdapter, new PatternTopic("chat"));
27 | return container;
28 | }
29 |
30 | @Bean
31 | MessageListenerAdapter listenerAdapter(Receiver receiver) {
32 | return new MessageListenerAdapter(receiver, "receiveMessage");
33 | }
34 |
35 | @Bean
36 | Receiver receiver() {
37 | return new Receiver();
38 | }
39 |
40 | @Bean
41 | StringRedisTemplate template(RedisConnectionFactory connectionFactory) {
42 | return new StringRedisTemplate(connectionFactory);
43 | }
44 | public static void main(String[] args) throws InterruptedException {
45 | ApplicationContext ctx = SpringApplication.run(SpringRedisApplication.class, args);
46 | StringRedisTemplate template = ctx.getBean(StringRedisTemplate.class);
47 | Receiver receiver = ctx.getBean(Receiver.class);
48 |
49 | while (receiver.getCount() == 0) {
50 | LOGGER.info("Waiting for messages...");
51 | template.convertAndSend("chat", "Hello from redis!");
52 | Thread.sleep(500L);
53 | }
54 | System.exit(0);
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @rem
2 | @rem Copyright 2015 the original author or authors.
3 | @rem
4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
5 | @rem you may not use this file except in compliance with the License.
6 | @rem You may obtain a copy of the License at
7 | @rem
8 | @rem https://www.apache.org/licenses/LICENSE-2.0
9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 |
17 | @if "%DEBUG%" == "" @echo off
18 | @rem ##########################################################################
19 | @rem
20 | @rem Gradle startup script for Windows
21 | @rem
22 | @rem ##########################################################################
23 |
24 | @rem Set local scope for the variables with windows NT shell
25 | if "%OS%"=="Windows_NT" setlocal
26 |
27 | set DIRNAME=%~dp0
28 | if "%DIRNAME%" == "" set DIRNAME=.
29 | set APP_BASE_NAME=%~n0
30 | set APP_HOME=%DIRNAME%
31 |
32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
34 |
35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
37 |
38 | @rem Find java.exe
39 | if defined JAVA_HOME goto findJavaFromJavaHome
40 |
41 | set JAVA_EXE=java.exe
42 | %JAVA_EXE% -version >NUL 2>&1
43 | if "%ERRORLEVEL%" == "0" goto execute
44 |
45 | echo.
46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
47 | echo.
48 | echo Please set the JAVA_HOME variable in your environment to match the
49 | echo location of your Java installation.
50 |
51 | goto fail
52 |
53 | :findJavaFromJavaHome
54 | set JAVA_HOME=%JAVA_HOME:"=%
55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
56 |
57 | if exist "%JAVA_EXE%" goto execute
58 |
59 | echo.
60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
61 | echo.
62 | echo Please set the JAVA_HOME variable in your environment to match the
63 | echo location of your Java installation.
64 |
65 | goto fail
66 |
67 | :execute
68 | @rem Setup the command line
69 |
70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
71 |
72 |
73 | @rem Execute Gradle
74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
75 |
76 | :end
77 | @rem End local scope for the variables with windows NT shell
78 | if "%ERRORLEVEL%"=="0" goto mainEnd
79 |
80 | :fail
81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
82 | rem the _cmd.exe /c_ return code!
83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
84 | exit /b 1
85 |
86 | :mainEnd
87 | if "%OS%"=="Windows_NT" endlocal
88 |
89 | :omega
90 |
--------------------------------------------------------------------------------
/redis-crud/src/main/java/com/villainscode/redis/rediskey/RedisKeyController.java:
--------------------------------------------------------------------------------
1 | package com.villainscode.redis.rediskey;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 | import java.util.Set;
6 | import lombok.extern.slf4j.Slf4j;
7 | import org.springframework.beans.factory.annotation.Autowired;
8 | import org.springframework.http.HttpStatus;
9 | import org.springframework.http.ResponseEntity;
10 | import org.springframework.web.bind.annotation.DeleteMapping;
11 | import org.springframework.web.bind.annotation.GetMapping;
12 | import org.springframework.web.bind.annotation.PostMapping;
13 | import org.springframework.web.bind.annotation.PutMapping;
14 | import org.springframework.web.bind.annotation.RequestMapping;
15 | import org.springframework.web.bind.annotation.RequestParam;
16 | import org.springframework.web.bind.annotation.RestController;
17 |
18 | /**
19 | * @author CodeVillains description :
20 | */
21 | @Slf4j
22 | @RestController
23 | @RequestMapping("/api/v1")
24 | public class RedisKeyController {
25 |
26 | private final RedisKeyService redisKeyService;
27 |
28 | @Autowired
29 | public RedisKeyController(RedisKeyService redisKeyService) {
30 | this.redisKeyService = redisKeyService;
31 | }
32 |
33 | // GET http://localhost:8080/api/v1/keys
34 | @GetMapping("/keys")
35 | public Set getAllKeys() {
36 | log.info("# getAllKeys");
37 | return redisKeyService.getAllKeys();
38 | }
39 |
40 | @GetMapping("/getAll")
41 | public ResponseEntity