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:
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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'
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user