Spring Boot资源服务器对接Spring Session与嵌入式Redis失败排查
我们出于评估需求,尝试将Spring Session与Embedded-Redis服务器结合使用。在Spring Boot 2.6.7 + JDK17环境中,Embedded-Redis服务器已随UI服务器启动,但接收Spring Session令牌的资源服务器无法连接Redis,且添加spring-session-data-redis依赖时出现方法不存在的错误。
资源服务器相关信息
代码实现
@SpringBootApplication @RestController public class ResourceApplication extends WebSecurityConfigurerAdapter { private final static Logger logger = LoggerFactory.getLogger(ResourceApplication.class); @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and().authorizeRequests().anyRequest().authenticated(); } @RequestMapping("/") @CrossOrigin(origins = "*", maxAge = 3600, allowedHeaders = { "x-auth-token", "x-requested-with", "x-xsrf-token" }) public Message home() { logger.info( "ResourceServer: home()"); return new Message("Hello World"); } @Bean HeaderHttpSessionStrategy sessionStrategy() { return new HeaderHttpSessionStrategy(); } public static void main(String[] args) { SpringApplication.run(ResourceApplication.class, args); } }
配置文件
security.sessions=NEVER spring.session.store-type=redis spring.redis.host=localhost spring.redis.port=6379
依赖配置
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session</artifactId> <version>1.3.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
错误信息
An attempt was made to call a method that does not exist. The attempt
was made from the following location:
org.springframework.boot.autoconfigure.session.RedisSessionConfiguration$SpringBootRedisHttpSessionConfiguration.customize(RedisSessionConfiguration.java:80)
添加spring-sessions-data-redis依赖时会出现相同错误。
Embedded Redis服务器相关信息
代码实现
@SpringBootApplication @EnableWebSecurity public class DemoApplication { private Logger logger = LoggerFactory.getLogger(getClass()); private RedisServer redisServer; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @PostConstruct public void startRedis() throws IOException { try { redisServer = RedisServer.builder().setting("maxheap 256Mb").port(6379).build(); redisServer.start(); } catch (Exception e) { e.printStackTrace(); } } @PreDestroy public void stopRedis(){ redisServer.stop(); } }
依赖配置
<dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session</artifactId> <version>1.3.5.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> </dependency> <dependency> <groupId>it.ozimov</groupId> <artifactId>embedded-redis</artifactId> <version>0.7.3</version> </dependency>
配置文件
spring.redis.host=localhost spring.redis.password= spring.redis.port=6379 spring.session.store-type=redis
解决方案
1. 修复核心依赖冲突
Spring Boot 2.6.7对应的Spring Session版本为2.6.x系列,你当前使用的spring-session 1.3.5.RELEASE是老旧版本,与Spring Boot 2.6.7完全不兼容,这是方法不存在错误的根源。
修改资源服务器和Embedded Redis服务器的依赖:
- 移除单独指定版本的
spring-session依赖,直接使用spring-boot-starter-data-redis和spring-session-data-redis,Spring Boot的依赖管理会自动匹配兼容版本。
资源服务器依赖修改为:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
Embedded Redis服务器依赖修改为:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency> <dependency> <groupId>it.ozimov</groupId> <artifactId>embedded-redis</artifactId> <version>0.7.3</version> </dependency>
2. 替换废弃的Session策略
HeaderHttpSessionStrategy在新版本Spring Session中已被弃用,替换为HeaderSessionIdResolver:
@Bean public SessionIdResolver sessionIdResolver() { return HeaderSessionIdResolver.xAuthToken(); // 对应配置中的x-auth-token请求头 }
3. 确保Embedded Redis完全启动
在Embedded Redis启动代码中添加等待逻辑,确保Redis服务完全就绪后再允许其他服务连接:
@PostConstruct public void startRedis() throws IOException { try { redisServer = RedisServer.builder().setting("maxheap 256Mb").port(6379).build(); redisServer.start(); // 等待Redis启动完成,最多重试10次 Jedis jedis = new Jedis("localhost", 6379); int retryCount = 0; while (!jedis.isConnected() && retryCount < 10) { Thread.sleep(1000); jedis.connect(); retryCount++; } jedis.close(); } catch (Exception e) { e.printStackTrace(); } }
(需添加Jedis依赖,或使用Spring的RedisTemplate进行连接校验)
4. 验证资源服务器Redis连接
在资源服务器中添加连接测试代码,确认Redis连接状态:
@Bean public CommandLineRunner redisConnectionTest(RedisTemplate<String, Object> redisTemplate) { return args -> { try { redisTemplate.opsForValue().set("test-key", "test-value"); String value = (String) redisTemplate.opsForValue().get("test-key"); System.out.println("Redis连接正常,测试值:" + value); } catch (Exception e) { System.err.println("Redis连接失败:" + e.getMessage()); } }; }
内容的提问来源于stack exchange,提问作者tm1701

