# redis Companion project for **[Redis with Spring Boot 4.1](https://ankurm.com/redis-with-spring-boot-4-1/)** on [ankurm.com](https://ankurm.com). Every key dump, error message and `redis-cli` reply quoted in the article came out of `docs/output/`, and every one of those files is regenerated by one script. Fifteen of the seventeen are produced by the test suite, which runs the real `redis-cli` against a real `redis-server`, so if a claim stops being true the build goes red. ## Versions | | | |---|---| | Spring Boot | 4.1.1 | | Spring Data Redis | 4.1.1 | | Lettuce | 7.5.2 | | Jackson | 3.1.5 (`tools.jackson`) | | Redis server | 7.0.15 | | JDK | 25 (Temurin 25.0.4.1+1) | | Maven | 3.9 | ## Quickstart ```bash export JAVA_HOME=/path/to/jdk-25 ./scripts/run-all.sh # regenerates every file under docs/output/ ``` You need `redis-server` and `redis-cli` (7.x) on the `PATH`. The tests start a throwaway server on port **6390** and stop it when the JVM exits. They call `FLUSHALL`, so they refuse to run if something is already listening on 6390. To look at the keys a test leaves behind, run a single test and watch the console: every transcript is echoed as it is written, and `docs/output/` keeps the last run. ## Where things are | Test | Demonstrates | Transcripts | |---|---|---| | [DefaultTemplateTest](src/test/java/com/ankurm/redis/DefaultTemplateTest.java) | The JDK-serialised default `RedisTemplate`: unreadable keys, non-Serializable values, the counter trap | 01, 02, 03 | | [StringTemplateTest](src/test/java/com/ankurm/redis/StringTemplateTest.java) | `StringRedisTemplate`, and two templates not sharing keys | 04, 05 | | [JacksonSerializerTest](src/test/java/com/ankurm/redis/JacksonSerializerTest.java) | Jackson 3 typed and generic serializers, the `@class` allow-list | 06, 07 | | [RedisHashTest](src/test/java/com/ankurm/redis/RedisHashTest.java) | `@RedisHash`, `CrudRepository`, index sets | 08 | | [HashTtlEventsOffTest](src/test/java/com/ankurm/redis/HashTtlEventsOffTest.java) / [HashTtlEventsOnTest](src/test/java/com/ankurm/redis/HashTtlEventsOnTest.java) | `@RedisHash(timeToLive)` with keyspace events off and on | 09, 10 | | [PubSubTest](src/test/java/com/ankurm/redis/PubSubTest.java) | `@RedisListener`, receivers count, lost messages | 11, 12 | | [TtlTest](src/test/java/com/ankurm/redis/TtlTest.java) | `getExpire`, `keepTtl`, `persist`, `setIfAbsent` | 13 | | [RedisCacheDefaultTest](src/test/java/com/ankurm/redis/RedisCacheDefaultTest.java) / [RedisCacheJsonTest](src/test/java/com/ankurm/redis/RedisCacheJsonTest.java) | Redis as the Spring cache, JDK vs JSON values | 14, 15 | | [scripts/capture-javap.sh](scripts/capture-javap.sh) | Serializer classes and deprecations, Boot's beans, read from the jars | 16 | | [scripts/capture-dependencies.sh](scripts/capture-dependencies.sh) | What the starter brings, and what it does not | 17 | ## Profiles | Profile | What it changes | |---|---| | *(none)* | Boot's defaults everywhere | | `json-cache` | A `RedisCacheConfiguration` bean that stores cache values as JSON with a 5-minute TTL | ## Documentation | Chapter | Covers | |---|---| | [1. What Boot gives you](docs/01-what-boot-gives-you.md) | Starter contents, auto-configured beans, the test setup | | [2. Default serialization](docs/02-default-serialization.md) | Why redis-cli shows garbage; the counter trap | | [3. StringRedisTemplate and two keyspaces](docs/03-string-template-and-two-keyspaces.md) | Text templates; why two templates miss each other's keys | | [4. JSON serializers](docs/04-json-serializers.md) | Jackson 3 typed vs generic; deprecations; the `@class` allow-list | | [5. @RedisHash](docs/05-redis-hash.md) | The six keys two entities create | | [6. Hash TTL and keyspace events](docs/06-hash-ttl-and-keyspace-events.md) | Leftover index entries; phantom keys; `RedisKeyExpiredEvent` | | [7. Pub/Sub](docs/07-pub-sub.md) | `@RedisListener`, receiver counts, at-most-once | | [8. TTL](docs/08-ttl.md) | -1 and -2, truncation, plain `set` clearing a TTL | | [9. Redis as the Spring cache](docs/09-redis-as-cache.md) | Serializable results, JSON, the property that stops applying | | [10. Production checklist](docs/10-production-checklist.md) | One line per lesson | ## Captured output | File | What | |---|---| | [01-default-template.txt](docs/output/01-default-template.txt) | The default template's key and value bytes | | [02-default-template-not-serializable.txt](docs/output/02-default-template-not-serializable.txt) | A non-Serializable value is rejected; a Serializable one embeds its class name | | [03-default-template-increment.txt](docs/output/03-default-template-increment.txt) | INCR works, the next read fails | | [04-string-template.txt](docs/output/04-string-template.txt) | StringRedisTemplate through value, counter, hash, list, set, sorted set | | [05-two-templates-two-keyspaces.txt](docs/output/05-two-templates-two-keyspaces.txt) | Same key name, two different keys | | [06-jackson-serializers.txt](docs/output/06-jackson-serializers.txt) | Typed, generic with allow-list, generic without typing | | [07-jackson-untrusted-class.txt](docs/output/07-jackson-untrusted-class.txt) | A class outside the allow-list; a class that no longer exists | | [08-redis-hash.txt](docs/output/08-redis-hash.txt) | The keys, hash fields and index sets of `@RedisHash` | | [09-hash-ttl-events-off.txt](docs/output/09-hash-ttl-events-off.txt) | Leftovers after a hash expires with Boot's defaults | | [10-hash-ttl-events-on.txt](docs/output/10-hash-ttl-events-on.txt) | Phantom key, server setting and expiry event with `ON_STARTUP` | | [11-pub-sub.txt](docs/output/11-pub-sub.txt) | Receiver counts, late listener, pattern subscription | | [12-pub-sub-lost-message.txt](docs/output/12-pub-sub-lost-message.txt) | A message published while the container is stopped | | [13-ttl.txt](docs/output/13-ttl.txt) | TTL read, set, cleared, kept, persisted | | [14-cache-default.txt](docs/output/14-cache-default.txt) | The Redis cache with Boot's defaults | | [15-cache-json.txt](docs/output/15-cache-json.txt) | The Redis cache with a JSON value serializer | | [16-serializers-javap.txt](docs/output/16-serializers-javap.txt) | Serializer classes, deprecations, Boot beans, `@RedisListener` | | [17-dependencies.txt](docs/output/17-dependencies.txt) | The starter's dependencies and the dependency tree |