手写企业级 Starter:ark-redis-starter(缓存 + 开关 + 降级策略)
一、前言
在使用 Spring Boot 的过程中,我们经常会遇到这样的需求:
- 想快速接入 Redis 缓存
- 想通过配置控制开关
- 想在 Redis 不可用时自动降级
如果每个项目都手写这些逻辑,会非常重复。
👉 这时候就可以用Starter来解决。
二、本篇目标
实现一个企业级简化版 Starter:
ark-redis-starter具备能力:
- ✅ 自动注入缓存服务
- ✅ 支持 application.yml 配置
- ✅ 支持开关控制
- ✅ 支持降级策略(Redis不可用时走本地缓存)
三、最终使用效果
用户只需要:
1️⃣ 引入依赖
<dependency> <groupId>com.ark</groupId> <artifactId>ark-redis-starter</artifactId> <version>1.0.0</version> </dependency>2️⃣ 写配置
ark: redis: enabled: true fallback: true prefix: ark:3️⃣ 直接使用
@Autowired private ArkCacheService cacheService; cacheService.set("key", "value");四、整体结构
ark-redis-starter ├── service │ ├── ArkCacheService.java │ ├── RedisCacheService.java │ └── LocalCacheService.java ├── properties │ └── ArkRedisProperties.java ├── autoconfigure │ └── ArkRedisAutoConfiguration.java └── resources └── META-INF/spring/ └── AutoConfiguration.imports五、第一步:配置类(核心)
package com.ark.starter.properties; import org.springframework.boot.context.properties.ConfigurationProperties; @ConfigurationProperties(prefix = "ark.redis") public class ArkRedisProperties { private boolean enabled = true; private boolean fallback = true; private String prefix = "ark:"; public boolean isEnabled() { return enabled; } public void setEnabled(boolean enabled) { this.enabled = enabled; } public boolean isFallback() { return fallback; } public void setFallback(boolean fallback) { this.fallback = fallback; } public String getPrefix() { return prefix; } public void setPrefix(String prefix) { this.prefix = prefix; } }六、第二步:定义统一接口
package com.ark.starter.service; public interface ArkCacheService { void set(String key, Object value); Object get(String key); }七、第三步:Redis 实现
package com.ark.starter.service; import org.springframework.data.redis.core.StringRedisTemplate; public class RedisCacheService implements ArkCacheService { private final StringRedisTemplate redisTemplate; private final String prefix; public RedisCacheService(StringRedisTemplate redisTemplate, String prefix) { this.redisTemplate = redisTemplate; this.prefix = prefix; } @Override public void set(String key, Object value) { redisTemplate.opsForValue().set(prefix + key, value.toString()); } @Override public Object get(String key) { return redisTemplate.opsForValue().get(prefix + key); } }八、第四步:本地缓存降级实现
package com.ark.starter.service; import java.util.concurrent.ConcurrentHashMap; public class LocalCacheService implements ArkCacheService { private final ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>(); @Override public void set(String key, Object value) { cache.put(key, value); } @Override public Object get(String key) { return cache.get(key); } }九、第五步:自动配置类(核心)
package com.ark.starter.autoconfigure; import com.ark.starter.properties.ArkRedisProperties; import com.ark.starter.service.*; import org.springframework.boot.autoconfigure.condition.*; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.core.StringRedisTemplate; @Configuration @EnableConfigurationProperties(ArkRedisProperties.class) @ConditionalOnProperty(prefix = "ark.redis", name = "enabled", havingValue = "true", matchIfMissing = true) public class ArkRedisAutoConfiguration { @Bean @ConditionalOnClass(StringRedisTemplate.class) public ArkCacheService redisCacheService(StringRedisTemplate redisTemplate, ArkRedisProperties properties) { return new RedisCacheService(redisTemplate, properties.getPrefix()); } @Bean @ConditionalOnMissingBean(ArkCacheService.class) @ConditionalOnProperty(prefix = "ark.redis", name = "fallback", havingValue = "true", matchIfMissing = true) public ArkCacheService localCacheService() { return new LocalCacheService(); } }十、第六步:注册自动配置
文件路径:
src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
内容:
com.ark.starter.autoconfigure.ArkRedisAutoConfiguration十一、核心运行流程
1. 引入 starter 2. Spring Boot 启动 3. 加载 AutoConfiguration 4. 判断 Redis 是否存在 5. 存在 → 用 RedisCacheService 6. 不存在 → fallback → LocalCacheService 7. 注入 ArkCacheService十二、核心设计点总结
🔥 1. 条件装配
@ConditionalOnClass👉 判断 Redis 是否存在
🔥 2. 开关控制
@ConditionalOnProperty👉 控制是否启用功能
🔥 3. 降级策略
@ConditionalOnMissingBean👉 Redis 不可用 → 自动 fallback
🔥 4. 配置驱动
@ConfigurationProperties👉 application.yml 控制行为
十三、你可以怎么讲这个项目(面试)
标准话术
我实现了一个自定义 Starter,用于统一缓存访问。
通过 @ConditionalOnClass 判断 Redis 是否存在,
使用 @ConditionalOnProperty 控制开关,
同时提供本地缓存作为降级策略,
最终通过接口抽象实现可插拔缓存架构。
十四、总结一句话
❗ Starter 的本质:
让用户“引依赖 + 写配置”就能获得完整能力
十五、最后(重点)
做完这个 Starter,其实已经具备:
- 自动装配能力
- 条件装配理解
- 配置驱动能力
- 基础架构设计能力
👉 这已经是中级后端 + 架构意识的水平。
