com.xxx.firstboot ├── common.MyConstants // 緩存前綴常量 ├── domain.User // 實體 ├── redis │ ├── RedisProperties // @ConfigurationProperties 綁定配置 │ ├── JedisClusterConfig // @Configuration + @Bean 暴露單例 JedisCluster │ └── MyRedisTemplate // 封裝 set/get/del/expire 等業務方法 ├── service.UserService ├── web.UserController // REST 測試端點 └── Application // 啟動類
redis.cache.clusterNodes=localhost:8080,localhost:8081 # 多節點逗號分隔
redis.cache.commandTimeout=5000 # 毫秒
redis.cache.expireSeconds=120 # 默認過期時間
@Component
@ConfigurationProperties(prefix = "redis.cache")
public class RedisProperties {
private int expireSeconds;
private String clusterNodes;
private int commandTimeout;
// getter/setter
}
@Configuration
public class JedisClusterConfig {
@Autowired RedisProperties props;
@Bean
public JedisCluster jedisCluster() {
Set<HostAndPort> nodes = new HashSet<>();
for (String hp : props.getClusterNodes().split(",")) {
String[] p = hp.split(":");
nodes.add(new HostAndPort(p[0].trim(), Integer.parseInt(p[1].trim())));
}
return new JedisCluster(nodes, props.getCommandTimeout());
// 生產建議補全 JedisPoolConfig:maxTotal, maxIdle, minIdle, maxWaitMillis 等
}
}
關鍵點:@Bean 方法返回單例,可直接 @Autowired 注入其他組件;若用 @Component 類級別則每次調用產生新實例。
@Component
public class MyRedisTemplate {
@Autowired JedisCluster jedisCluster;
@Autowired RedisProperties props;
private static final String SPLIT = ":";
public void set(String prefix, String key, String val) {
jedisCluster.set(prefix + SPLIT + key, val);
}
public void setWithExpireTime(String prefix, String key, String val) {
jedisCluster.setex(prefix + SPLIT + key, props.getExpireSeconds(), val);
}
public String get(String prefix, String key) {
return jedisCluster.get(prefix + SPLIT + key);
}
public void delete(String prefix, String key) {
jedisCluster.del(prefix + SPLIT + key);
}
// List/Set/ZSet/Hash 操作同理調用 jedisCluster 對應 API
}
public class MyConstants {
public static final String USER_FORWARD_CACHE_PREFIX = "myboot:user";
}
redis-cli --scan --pattern "myboot:user:*" 批量運維。@RestController
@RequestMapping("/user")
public class UserController {
@Autowired UserService userService;
@Autowired MyRedisTemplate redis;
@GetMapping("/testJedisCluster")
public User test(@RequestParam String username) {
String val = redis.get(MyConstants.USER_FORWARD_CACHE_PREFIX, username);
if (StringUtils.isBlank(val)) {
redis.set(MyConstants.USER_FORWARD_CACHE_PREFIX, username, JSON.toJSONString(userService.getUser()));
return null; // 首次預熱
}
return JSON.parseObject(val, User.class);
}
}
localhost:8080/user/testJedisCluster?username=xxx 兩次,第二次應命中緩存;JedisPoolConfig:連接池大小、閒置驗證、獲取超時;readFromReplicas 讀寫分離;