Add redis: Boot 4.1 + Spring Data Redis 4.1, the JDK-serialisation default vs Jackson 3 serializers, @RedisHash TTL and keyspace events, @RedisListener, and Redis as the Spring cache

Co-Authored-By: Claude Sonnet 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01B38FGKKam5SCGgwgduVAh3
This commit is contained in:
Claude
2026-09-21 15:46:55 +00:00
parent 8cdfcd4d8d
commit b0c39a8d4c
60 changed files with 2900 additions and 1 deletions
+20
View File
@@ -0,0 +1,20 @@
# The RedisTemplate Boot gives you: JDK serialisation for keys and values
--- Which serializers is it using? ---
key serializer: JdkSerializationRedisSerializer
value serializer: JdkSerializationRedisSerializer
--- Write a String under the key user:1 ---
redisTemplate.opsForValue().set("user:1", "Ankur")
--- What redis-cli sees ---
$ redis-cli -p 6390 --no-raw KEYS '*'
1) "\xac\xed\x00\x05t\x00\x06user:1"
$ redis-cli -p 6390 --no-raw GET user:1
(nil)
$ redis-cli -p 6390 --no-raw EVAL 'return redis.call("GET", redis.call("KEYS", "*")[1])' 0
"\xac\xed\x00\x05t\x00\x05Ankur"
--- What Java sees ---
redisTemplate.opsForValue().get("user:1") = Ankur
@@ -0,0 +1,16 @@
# The default template refuses a value that is not java.io.Serializable
--- A record that does not implement Serializable ---
redisTemplate.opsForValue().set("user:2", new User(2, "Ankur"))
org.springframework.data.redis.serializer.SerializationException
message: Cannot serialize
cause: Failed to serialize object using DefaultSerializer
root: DefaultSerializer requires a Serializable payload but received an object of type [com.ankurm.redis.model.User]
keys afterwards: 0
--- The same shape, implementing Serializable ---
redisTemplate.opsForValue().set("user:3", new SerializableUser(3, "Ankur"))
$ redis-cli -p 6390 --no-raw EVAL 'return redis.call("GET", redis.call("KEYS", "*")[1])' 0
"\xac\xed\x00\x05sr\x00'com.ankurm.redis.model.SerializableUser\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02J\x00\x02idL\x00\x04namet\x00\x12Ljava/lang/String;xp\x00\x00\x00\x00\x00\x00\x00\x03t\x00\x05Ankur"
read back: SerializableUser[id=3, name=Ankur]
@@ -0,0 +1,17 @@
# INCR works with the default template, but the template cannot read the counter it made
--- Increment a counter ---
redisTemplate.opsForValue().increment("hits") = 1
--- What redis-cli sees ---
$ redis-cli -p 6390 --no-raw KEYS '*'
1) "\xac\xed\x00\x05t\x00\x04hits"
$ redis-cli -p 6390 --no-raw EVAL 'return redis.call("GET", redis.call("KEYS", "*")[1])' 0
"1"
--- Read it back through the same template ---
redisTemplate.opsForValue().get("hits")
org.springframework.data.redis.serializer.SerializationException
message: Cannot deserialize
root: java.io.EOFException: null
+45
View File
@@ -0,0 +1,45 @@
# StringRedisTemplate: every key and value is UTF-8 text
--- Which serializers is it using? ---
key serializer: StringRedisSerializer
value serializer: StringRedisSerializer
hash key serializer: StringRedisSerializer
hash value serializer: StringRedisSerializer
--- A string value ---
stringTemplate.opsForValue().set("user:1", "Ankur")
$ redis-cli -p 6390 --no-raw GET user:1
"Ankur"
--- A counter ---
stringTemplate.opsForValue().increment("hits") twice = 2
$ redis-cli -p 6390 --no-raw GET hits
"2"
--- A hash ---
stringTemplate.opsForHash().put("user:1:profile", "city", "Pune") and ("editor", "vim")
$ redis-cli -p 6390 --no-raw HGETALL user:1:profile
1) "city"
2) "Pune"
3) "editor"
4) "vim"
--- A list, a set and a sorted set ---
$ redis-cli -p 6390 --no-raw LRANGE queue 0 -1
1) "a"
2) "b"
3) "c"
$ redis-cli -p 6390 SMEMBERS tags | sort
java
spring
$ redis-cli -p 6390 --no-raw ZRANGE scores 0 -1 WITHSCORES
1) "ankur"
2) "42"
$ redis-cli -p 6390 KEYS '*' | sort
hits
queue
scores
tags
user:1
user:1:profile
@@ -0,0 +1,16 @@
# Same key name, two templates, two different keys
--- Write user:1 with StringRedisTemplate ---
stringTemplate.opsForValue().get("user:1") = from-string-template
redisTemplate.opsForValue().get("user:1") = null
--- Write user:1 with the default RedisTemplate ---
stringTemplate.opsForValue().get("user:1") = from-string-template
redisTemplate.opsForValue().get("user:1") = from-default-template
--- What Redis holds ---
$ redis-cli -p 6390 --no-raw DBSIZE
(integer) 2
$ redis-cli -p 6390 --no-raw GET user:1
"from-string-template"
@@ -0,0 +1,30 @@
# Jackson 3 serializers: JacksonJsonRedisSerializer and GenericJacksonJsonRedisSerializer
--- JacksonJsonRedisSerializer<User>: one type, plain JSON ---
value serializer: org.springframework.data.redis.serializer.JacksonJsonRedisSerializer
userTemplate.opsForValue().set("user:1", new User(1, "Ankur"))
$ redis-cli -p 6390 KEYS '*'
user:1
$ redis-cli -p 6390 GET user:1
{"id":1,"name":"Ankur"}
read back: User[id=1, name=Ankur] (User)
--- GenericJacksonJsonRedisSerializer with an allow-list: any type, plus @class ---
value serializer: org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer
jsonTemplate.opsForValue().set("user:2", new User(2, "Ankur"))
$ redis-cli -p 6390 GET user:2
{"@class":"com.ankurm.redis.model.User","id":2,"name":"Ankur"}
read back: User[id=2, name=Ankur] (User)
--- GenericJacksonJsonRedisSerializer with no typing configured ---
plain.opsForValue().set("user:3", new User(3, "Ankur"))
$ redis-cli -p 6390 GET user:3
{"id":3,"name":"Ankur"}
read back: {id=3, name=Ankur} (LinkedHashMap)
--- Two different shapes of the same JSON ---
$ redis-cli -p 6390 GET user:1
{"id":1,"name":"Ankur"}
$ redis-cli -p 6390 GET user:2
{"@class":"com.ankurm.redis.model.User","id":2,"name":"Ankur"}
@@ -0,0 +1,16 @@
# The @class property is input: the allow-list decides what it may name
--- A class outside the allow-list ---
$ redis-cli -p 6390 SET user:evil '{"@class":"com.ankurm.other.Outsider","name":"x"}'
OK
jsonTemplate.opsForValue().get("user:evil")
org.springframework.data.redis.serializer.SerializationException
message: Could not read JSON: Could not resolve type id 'com.ankurm.other.Outsider' as a subtype of `com.ankurm.other.Outsider`: Configured `PolymorphicTypeValidator` (of type `tools.jackson.databind.jsontype.BasicPolymorphicTypeValidator`) denied resolution
--- A class inside the allow-list that no longer exists ---
$ redis-cli -p 6390 SET user:gone '{"@class":"com.ankurm.redis.model.Gone","id":9}'
OK
jsonTemplate.opsForValue().get("user:gone")
org.springframework.data.redis.serializer.SerializationException
message: Could not read JSON: Failed to parse type 'com.ankurm.redis.model.Gone' (remaining: ''): Cannot locate class 'com.ankurm.redis.model.Gone', problem: com.ankurm.redis.model.Gone
+61
View File
@@ -0,0 +1,61 @@
# @RedisHash and CrudRepository: the keys Spring Data Redis creates
--- Save two people ---
people.save(new Person("1", "Ankur", "Mhatre", 40))
people.save(new Person("2", "Asha", "Mhatre", 38))
--- Every key it created ---
$ redis-cli -p 6390 KEYS '*' | sort
person
person:1
person:1:idx
person:2
person:2:idx
person:lastName:Mhatre
--- The entity is a hash ---
$ redis-cli -p 6390 --no-raw TYPE person:1
hash
$ redis-cli -p 6390 --no-raw HGETALL person:1
1) "_class"
2) "com.ankurm.redis.hash.Person"
3) "age"
4) "40"
5) "firstName"
6) "Ankur"
7) "id"
8) "1"
9) "lastName"
10) "Mhatre"
--- The keyspace is a set of ids ---
$ redis-cli -p 6390 SMEMBERS person | sort
1
2
--- The @Indexed field is a set per value ---
$ redis-cli -p 6390 SMEMBERS person:lastName:Mhatre | sort
1
2
--- And each entity remembers which index sets it is in ---
$ redis-cli -p 6390 SMEMBERS person:1:idx | sort
person:lastName:Mhatre
--- What the repository returns ---
people.findById("1") = Person[id=1, Ankur Mhatre, age=40]
people.count() = 2
people.findByLastName("Mhatre") = 2 results
--- Delete one, and look again ---
people.deleteById("1")
$ redis-cli -p 6390 KEYS '*' | sort
person
person:2
person:2:idx
person:lastName:Mhatre
$ redis-cli -p 6390 SMEMBERS person:lastName:Mhatre | sort
2
$ redis-cli -p 6390 SMEMBERS person | sort
2
@@ -0,0 +1,35 @@
# @RedisHash(timeToLive = 2) with Boot's defaults (keyspace events OFF)
--- Server setting ---
$ redis-cli -p 6390 --no-raw CONFIG GET notify-keyspace-events
1) "notify-keyspace-events"
2) ""
--- Save a session that lives for two seconds ---
sessions.save(new Session("s1", "ankur"))
$ redis-cli -p 6390 KEYS '*' | sort
session
session:s1
session:s1:idx
session:user:ankur
$ redis-cli -p 6390 --no-raw TTL session:s1
(integer) 2
--- Wait for Redis to expire it ---
$ redis-cli -p 6390 --no-raw EXISTS session:s1
(integer) 0
--- What is left behind ---
$ redis-cli -p 6390 KEYS '*' | sort
session
session:s1:idx
session:user:ankur
$ redis-cli -p 6390 SMEMBERS session | sort
s1
$ redis-cli -p 6390 SMEMBERS session:user:ankur | sort
s1
--- What the repository says ---
sessions.findById("s1") = Optional.empty
sessions.count() = 1
@@ -0,0 +1,33 @@
# @RedisHash(timeToLive = 2) with enableKeyspaceEvents = ON_STARTUP
--- Server setting before the application context started ---
$ redis-cli -p 6390 --no-raw CONFIG GET notify-keyspace-events
1) "notify-keyspace-events"
2) ""
--- Server setting now ---
$ redis-cli -p 6390 --no-raw CONFIG GET notify-keyspace-events
1) "notify-keyspace-events"
2) "xE"
--- Save a session that lives for two seconds ---
sessions.save(new Session("s1", "ankur"))
$ redis-cli -p 6390 KEYS '*' | sort
session
session:s1
session:s1:idx
session:s1:phantom
session:user:ankur
$ redis-cli -p 6390 --no-raw TTL session:s1
(integer) 2
$ redis-cli -p 6390 --no-raw TTL session:s1:phantom
(integer) 302
--- Wait for Redis to expire it, and for Spring to react ---
RedisKeyExpiredEvent: keyspace=session id=s1 value=Session[id=s1, user=ankur]
--- What is left behind ---
$ redis-cli -p 6390 --no-raw DBSIZE
(integer) 0
sessions.count() = 0
+38
View File
@@ -0,0 +1,38 @@
# Pub/Sub: what is delivered, to whom, and what is lost
--- The container Boot created ---
beans of type RedisMessageListenerContainer: [redisMessageListenerContainer]
running=true listening=true
--- Publishing to a channel nobody listens to ---
template.convertAndSend("quiet", "hello?") = 0 receivers
$ redis-cli -p 6390 --no-raw PUBSUB NUMSUB quiet
1) "quiet"
2) (integer) 0
--- Publishing to news, which has an @RedisListener ---
$ redis-cli -p 6390 --no-raw PUBSUB NUMSUB news
1) "news"
2) (integer) 1
template.convertAndSend("news", "first") = 1 receiver
@RedisListener got 'first'
--- A second listener that subscribes late ---
container.addMessageListener(late, new ChannelTopic("news"))
$ redis-cli -p 6390 --no-raw PUBSUB NUMSUB news
1) "news"
2) (integer) 1
template.convertAndSend("news", "second") = 1 receiver
@RedisListener got 'first'
@RedisListener got 'second'
late listener got 'second' on news
--- A pattern subscription (topic = "alerts.*") ---
$ redis-cli -p 6390 --no-raw PUBSUB NUMPAT
(integer) 1
$ redis-cli -p 6390 --no-raw PUBSUB NUMSUB alerts.disk
1) "alerts.disk"
2) (integer) 0
template.convertAndSend("alerts.disk", "90% full") = 1 receiver
@RedisListener got '90% full' on alerts.disk
@@ -0,0 +1,20 @@
# Pub/Sub is at-most-once: a stopped listener loses messages
--- Stop the listener container, then publish ---
container.stop()
$ redis-cli -p 6390 --no-raw PUBSUB NUMSUB news
1) "news"
2) (integer) 0
template.convertAndSend("news", "while you were away") = 0 receivers
--- Start it again ---
container.start()
$ redis-cli -p 6390 --no-raw PUBSUB NUMSUB news
1) "news"
2) (integer) 1
messages the listener has: []
--- Once it is back, messages flow again ---
template.convertAndSend("news", "welcome back") = 1 receiver
@RedisListener got 'welcome back'
+51
View File
@@ -0,0 +1,51 @@
# TTL: set, read, lose, keep and clear it
--- No TTL, and a key that does not exist ---
set("plain", "v")
getExpire("plain") = -1
getExpire("missing") = -2
--- Set a value with a Duration ---
set("session", "v1", Duration.ofMinutes(10))
getExpire("session") = 600
getExpire("session", TimeUnit.MINUTES) = 9
$ redis-cli -p 6390 --no-raw TTL session
(integer) 600
--- A plain set() afterwards throws the TTL away ---
set("session", "v2")
getExpire("session") = -1
$ redis-cli -p 6390 --no-raw TTL session
(integer) -1
--- Put a TTL back, then overwrite while keeping it ---
expire("session", Duration.ofMinutes(10))
set("session", "v3", Expiration.keepTtl())
getExpire("session") = 600, value = v3
$ redis-cli -p 6390 --no-raw TTL session
(integer) 600
--- Sub-second precision ---
set("short", "v", Duration.ofMillis(1500))
getExpire("short", TimeUnit.MILLISECONDS) <= 1500: true
getExpire("short") in seconds = 1
--- persist() removes a TTL ---
persist("session")
getExpire("session") = -1
--- Expiry actually happens ---
set("blink", "v", Duration.ofMillis(300))
get("blink") straight away = v
get("blink") later = null
$ redis-cli -p 6390 --no-raw EXISTS blink
(integer) 0
--- setIfAbsent with a TTL is the smallest lock ---
setIfAbsent("lock:job", "worker-1", 30s) = true
setIfAbsent("lock:job", "worker-2", 30s) = false
$ redis-cli -p 6390 --no-raw GET lock:job
"worker-1"
$ redis-cli -p 6390 --no-raw TTL lock:job
(integer) 30
+23
View File
@@ -0,0 +1,23 @@
# Redis as the Spring cache: what the defaults store
--- Which cache manager did Boot pick? ---
org.springframework.data.redis.cache.RedisCacheManager
--- A Serializable result, cached ---
findSerializable(1) called twice, method body ran 1 time(s)
$ redis-cli -p 6390 KEYS '*' | sort
legacy::1
$ redis-cli -p 6390 --no-raw TTL legacy::1
(integer) 600
$ redis-cli -p 6390 --no-raw GET legacy::1
"\xac\xed\x00\x05sr\x00'com.ankurm.redis.model.SerializableUser\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\x02J\x00\x02idL\x00\x04namet\x00\x12Ljava/lang/String;xp\x00\x00\x00\x00\x00\x00\x00\x01t\x00\x05Ankur"
--- A result that is not Serializable ---
users.find(1)
java.lang.IllegalStateException
message: Cannot serialize value of type com.ankurm.redis.model.User without a serializer
root: Cannot serialize value of type com.ankurm.redis.model.User without a serializer
method body ran 2 time(s) in total
$ redis-cli -p 6390 KEYS '*' | sort
legacy::1
+15
View File
@@ -0,0 +1,15 @@
# Redis as the Spring cache with a Jackson 3 value serializer
--- The result that was not Serializable now caches ---
find(1) called twice, method body ran 1 time(s)
second call returned: User[id=1, name=Ankur]
--- What is in Redis ---
$ redis-cli -p 6390 KEYS '*' | sort
users::1
$ redis-cli -p 6390 GET users::1
{"@class":"com.ankurm.redis.model.User","id":1,"name":"Ankur"}
$ redis-cli -p 6390 --no-raw TTL users::1
(integer) 300
spring.cache.redis.time-to-live=10m is set, and the bean says 5 minutes
@@ -0,0 +1,89 @@
# Serializer classes in spring-data-redis-4.1.1.jar, read from the jar
--- What ships in org/springframework/data/redis/serializer ---
$ unzip -l spring-data-redis-*.jar | grep serializer/ (top-level classes, names only)
ByteArrayRedisSerializer
GenericJackson2JsonRedisSerializer
GenericJacksonJsonRedisSerializer
GenericToStringSerializer
Jackson2JsonRedisSerializer
JacksonJsonRedisSerializer
JdkSerializationRedisSerializer
OxmSerializer
RedisSerializer
StringRedisSerializer
--- Which of them are deprecated ---
$ javap -v -cp spring-data-redis-*.jar org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer | grep -E 'Deprecated|since'
#377 = Utf8 Deprecated
#379 = Utf8 Ljava/lang/Deprecated;
#380 = Utf8 since
Deprecated: true
java.lang.Deprecated(
since="4.0"
(end of output for GenericJackson2JsonRedisSerializer)
$ javap -v -cp spring-data-redis-*.jar org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer | grep -E 'Deprecated|since'
#125 = Utf8 Deprecated
#127 = Utf8 Ljava/lang/Deprecated;
#128 = Utf8 since
Deprecated: true
java.lang.Deprecated(
since="3.0"
Deprecated: true
java.lang.Deprecated(
since="3.0"
Deprecated: true
java.lang.Deprecated(
since="4.0"
(end of output for Jackson2JsonRedisSerializer)
$ javap -v -cp spring-data-redis-*.jar org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer | grep -E 'Deprecated|since'
(end of output for GenericJacksonJsonRedisSerializer)
$ javap -v -cp spring-data-redis-*.jar org.springframework.data.redis.serializer.JacksonJsonRedisSerializer | grep -E 'Deprecated|since'
(end of output for JacksonJsonRedisSerializer)
--- Jackson 3: what the constructors and factories accept ---
$ javap -public -cp <classpath> org.springframework.data.redis.serializer.JacksonJsonRedisSerializer | grep 'JacksonJsonRedisSerializer('
public org.springframework.data.redis.serializer.JacksonJsonRedisSerializer(java.lang.Class<T>);
public org.springframework.data.redis.serializer.JacksonJsonRedisSerializer(tools.jackson.databind.JavaType);
public org.springframework.data.redis.serializer.JacksonJsonRedisSerializer(tools.jackson.databind.ObjectMapper, java.lang.Class<T>);
public org.springframework.data.redis.serializer.JacksonJsonRedisSerializer(tools.jackson.databind.ObjectMapper, tools.jackson.databind.JavaType);
public org.springframework.data.redis.serializer.JacksonJsonRedisSerializer(tools.jackson.databind.ObjectMapper, tools.jackson.databind.JavaType, org.springframework.data.redis.serializer.JacksonObjectReader, org.springframework.data.redis.serializer.JacksonObjectWriter);
$ javap -public -cp <classpath> org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer | grep -E 'GenericJacksonJsonRedisSerializer\(|create|builder'
public org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer(tools.jackson.databind.ObjectMapper);
public static org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer create(java.util.function.Consumer<org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer$GenericJacksonJsonRedisSerializerBuilder<tools.jackson.databind.json.JsonMapper$Builder>>);
public static org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer$GenericJacksonJsonRedisSerializerBuilder<tools.jackson.databind.json.JsonMapper$Builder> builder();
public static <B extends tools.jackson.databind.cfg.MapperBuilder<? extends tools.jackson.databind.ObjectMapper, ? extends tools.jackson.databind.cfg.MapperBuilder<?, ?>>> org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer$GenericJacksonJsonRedisSerializerBuilder<B> builder(java.util.function.Supplier<B>);
--- Jackson 3: how the generic serializer's builder turns typing on ---
$ javap -public -cp <classpath> 'org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer$GenericJacksonJsonRedisSerializerBuilder' | grep -E 'Typing|typeValidator|typePropertyName'
public org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer$GenericJacksonJsonRedisSerializerBuilder<B> enableUnsafeDefaultTyping();
public org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer$GenericJacksonJsonRedisSerializerBuilder<B> enableDefaultTyping(tools.jackson.databind.jsontype.PolymorphicTypeValidator);
public org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer$GenericJacksonJsonRedisSerializerBuilder<B> typeValidator(tools.jackson.databind.jsontype.PolymorphicTypeValidator);
public org.springframework.data.redis.serializer.GenericJacksonJsonRedisSerializer$GenericJacksonJsonRedisSerializerBuilder<B> typePropertyName(java.lang.String);
--- What Boot 4.1 registers ---
$ javap -p -cp spring-boot-data-redis-*.jar org.springframework.boot.data.redis.autoconfigure.DataRedisAutoConfiguration | grep -E 'redisTemplate|stringRedisTemplate'
org.springframework.data.redis.core.RedisTemplate<java.lang.Object, java.lang.Object> redisTemplate(org.springframework.data.redis.connection.RedisConnectionFactory);
org.springframework.data.redis.core.StringRedisTemplate stringRedisTemplate(org.springframework.data.redis.connection.RedisConnectionFactory);
$ javap -p -cp spring-boot-data-redis-*.jar org.springframework.boot.data.redis.autoconfigure.DataRedisAnnotationDrivenConfiguration | grep 'redisMessageListenerContainer'
org.springframework.boot.data.redis.autoconfigure.RedisMessageListenerContainerConfigurer redisMessageListenerContainerConfigurer();
org.springframework.data.redis.listener.RedisMessageListenerContainer redisMessageListenerContainer(org.springframework.boot.data.redis.autoconfigure.RedisMessageListenerContainerConfigurer, org.springframework.data.redis.connection.RedisConnectionFactory);
org.springframework.data.redis.listener.RedisMessageListenerContainer redisMessageListenerContainerVirtualThreads(org.springframework.boot.data.redis.autoconfigure.RedisMessageListenerContainerConfigurer, org.springframework.data.redis.connection.RedisConnectionFactory);
--- Defaults of @EnableRedisRepositories that matter for expiry ---
$ javap -v -cp spring-data-redis-*.jar org.springframework.data.redis.repository.configuration.EnableRedisRepositories | grep -A6 -E '(enableKeyspaceEvents|keyspaceNotificationsConfigParameter)\(\);' | grep -E '\(\);|"Ex"|\.OFF'
public abstract org.springframework.data.redis.core.RedisKeyValueAdapter$EnableKeyspaceEvents enableKeyspaceEvents();
Lorg/springframework/data/redis/core/RedisKeyValueAdapter$EnableKeyspaceEvents;.OFF
public abstract java.lang.String keyspaceNotificationsConfigParameter();
"Ex"
--- The @RedisListener annotation ---
$ javap -public -cp spring-data-redis-*.jar org.springframework.data.redis.annotation.RedisListener
Compiled from "RedisListener.java"
public interface org.springframework.data.redis.annotation.RedisListener extends java.lang.annotation.Annotation {
public abstract java.lang.String id();
public abstract java.lang.String container();
public abstract java.lang.String value();
public abstract java.lang.String topic();
public abstract java.lang.String consumes();
}
+32
View File
@@ -0,0 +1,32 @@
# What the Redis starter brings, and what it does not
--- The starter's own dependencies (from its pom) ---
$ grep -E 'artifactId|scope' spring-boot-starter-data-redis-*.pom
<artifactId>spring-boot-starter-data-redis</artifactId>
<artifactId>spring-boot-starter</artifactId>
<scope>compile</scope>
<artifactId>spring-boot-data-redis</artifactId>
<scope>compile</scope>
<artifactId>spring-messaging</artifactId>
<scope>compile</scope>
--- The client and JSON libraries in this module (mvn dependency:tree, filtered) ---
$ mvn dependency:tree -Dincludes=io.lettuce,redis.clients,tools.jackson.core,com.fasterxml.jackson.core,org.springframework.data,org.springframework:spring-messaging
com.ankurm:redis:jar:1.0.0
+- org.springframework.boot:spring-boot-starter-data-redis:jar:4.1.1:compile
| +- org.springframework.boot:spring-boot-data-redis:jar:4.1.1:compile
| | +- org.springframework.boot:spring-boot-data-commons:jar:4.1.1:compile
| | | \- org.springframework.data:spring-data-commons:jar:4.1.1:compile
| | +- io.lettuce:lettuce-core:jar:7.5.2.RELEASE:compile
| | \- org.springframework.data:spring-data-redis:jar:4.1.1:compile
| | \- org.springframework.data:spring-data-keyvalue:jar:4.1.1:compile
| \- org.springframework:spring-messaging:jar:7.0.9:compile
\- org.springframework.boot:spring-boot-starter-jackson:jar:4.1.1:compile
\- org.springframework.boot:spring-boot-jackson:jar:4.1.1:compile
\- tools.jackson.core:jackson-databind:jar:3.1.5:compile
+- com.fasterxml.jackson.core:jackson-annotations:jar:2.21:compile
\- tools.jackson.core:jackson-core:jar:3.1.5:compile
--- The server the tests start ---
$ redis-server --version
Redis server v=7.0.15 sha=00000000:0 malloc=jemalloc-5.3.0 bits=64 build=e53ff17674aa6190