Update Redis configuration to use bean classloader
Spring Session 2.0 made changes to Redis configuration facilities so that the `RedisTemplate` used by `RedisOperationsSessionRepository` isn't exposed as a bean anymore. This has a consequence that bean `ClassLoader` isn't applied automatically which causes issues in Spring Boot applications that use DevTools. This commit restores the previous behavior by updating Redis configuration classes to implement `BeanClassLoaderAware` callback and apply the application `ClassLoader` to `RedisTemplate`. The analogous change was made to reactive Redis configuration. Closes gh-968
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
* Copyright 2014-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,6 +23,7 @@ import java.util.concurrent.Executor;
|
||||
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@@ -70,7 +71,8 @@ import org.springframework.util.StringValueResolver;
|
||||
@Configuration
|
||||
@EnableScheduling
|
||||
public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguration
|
||||
implements EmbeddedValueResolverAware, ImportAware, SchedulingConfigurer {
|
||||
implements BeanClassLoaderAware, EmbeddedValueResolverAware, ImportAware,
|
||||
SchedulingConfigurer {
|
||||
|
||||
static final String DEFAULT_CLEANUP_CRON = "0 * * * * *";
|
||||
|
||||
@@ -94,12 +96,13 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
|
||||
private Executor redisSubscriptionExecutor;
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
private StringValueResolver embeddedValueResolver;
|
||||
|
||||
@Bean
|
||||
public RedisOperationsSessionRepository sessionRepository() {
|
||||
RedisTemplate<Object, Object> redisTemplate = createRedisTemplate(
|
||||
this.redisConnectionFactory, this.defaultRedisSerializer);
|
||||
RedisTemplate<Object, Object> redisTemplate = createRedisTemplate();
|
||||
RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(
|
||||
redisTemplate);
|
||||
sessionRepository.setApplicationEventPublisher(this.applicationEventPublisher);
|
||||
@@ -205,6 +208,11 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
this.redisSubscriptionExecutor = redisSubscriptionExecutor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEmbeddedValueResolver(StringValueResolver resolver) {
|
||||
this.embeddedValueResolver = resolver;
|
||||
@@ -235,16 +243,15 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
this.cleanupCron);
|
||||
}
|
||||
|
||||
private static RedisTemplate<Object, Object> createRedisTemplate(
|
||||
RedisConnectionFactory redisConnectionFactory,
|
||||
RedisSerializer<Object> defaultRedisSerializer) {
|
||||
private RedisTemplate<Object, Object> createRedisTemplate() {
|
||||
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||
if (defaultRedisSerializer != null) {
|
||||
redisTemplate.setDefaultSerializer(defaultRedisSerializer);
|
||||
if (this.defaultRedisSerializer != null) {
|
||||
redisTemplate.setDefaultSerializer(this.defaultRedisSerializer);
|
||||
}
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||
redisTemplate.setConnectionFactory(this.redisConnectionFactory);
|
||||
redisTemplate.setBeanClassLoader(this.classLoader);
|
||||
redisTemplate.afterPropertiesSet();
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
* Copyright 2014-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,6 +18,7 @@ package org.springframework.session.data.redis.config.annotation.web.server;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.EmbeddedValueResolverAware;
|
||||
@@ -53,11 +54,7 @@ import org.springframework.web.server.session.WebSessionManager;
|
||||
*/
|
||||
@Configuration
|
||||
public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
||||
implements EmbeddedValueResolverAware, ImportAware {
|
||||
|
||||
private static final RedisSerializer<String> keySerializer = new StringRedisSerializer();
|
||||
|
||||
private static final RedisSerializer<Object> valueSerializer = new JdkSerializationRedisSerializer();
|
||||
implements BeanClassLoaderAware, EmbeddedValueResolverAware, ImportAware {
|
||||
|
||||
private Integer maxInactiveIntervalInSeconds = MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;
|
||||
|
||||
@@ -67,12 +64,15 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
||||
|
||||
private ReactiveRedisConnectionFactory redisConnectionFactory;
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
private StringValueResolver embeddedValueResolver;
|
||||
|
||||
@Bean
|
||||
public ReactiveRedisOperationsSessionRepository sessionRepository() {
|
||||
ReactiveRedisTemplate<String, Object> reactiveRedisTemplate = createReactiveRedisTemplate();
|
||||
ReactiveRedisOperationsSessionRepository sessionRepository = new ReactiveRedisOperationsSessionRepository(
|
||||
createDefaultTemplate(this.redisConnectionFactory));
|
||||
reactiveRedisTemplate);
|
||||
sessionRepository
|
||||
.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);
|
||||
if (StringUtils.hasText(this.redisNamespace)) {
|
||||
@@ -107,6 +107,11 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
||||
this.redisConnectionFactory = redisConnectionFactoryToUse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEmbeddedValueResolver(StringValueResolver resolver) {
|
||||
this.embeddedValueResolver = resolver;
|
||||
@@ -127,12 +132,15 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
||||
this.redisFlushMode = attributes.getEnum("redisFlushMode");
|
||||
}
|
||||
|
||||
private static ReactiveRedisTemplate<String, Object> createDefaultTemplate(
|
||||
ReactiveRedisConnectionFactory connectionFactory) {
|
||||
private ReactiveRedisTemplate<String, Object> createReactiveRedisTemplate() {
|
||||
RedisSerializer<String> keySerializer = new StringRedisSerializer();
|
||||
RedisSerializer<Object> valueSerializer = new JdkSerializationRedisSerializer(
|
||||
this.classLoader);
|
||||
RedisSerializationContext<String, Object> serializationContext = RedisSerializationContext
|
||||
.<String, Object>newSerializationContext(valueSerializer)
|
||||
.key(keySerializer).hashKey(keySerializer).build();
|
||||
return new ReactiveRedisTemplate<>(connectionFactory, serializationContext);
|
||||
return new ReactiveRedisTemplate<>(this.redisConnectionFactory,
|
||||
serializationContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user