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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@@ -70,7 +71,8 @@ import org.springframework.util.StringValueResolver;
|
|||||||
@Configuration
|
@Configuration
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguration
|
public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguration
|
||||||
implements EmbeddedValueResolverAware, ImportAware, SchedulingConfigurer {
|
implements BeanClassLoaderAware, EmbeddedValueResolverAware, ImportAware,
|
||||||
|
SchedulingConfigurer {
|
||||||
|
|
||||||
static final String DEFAULT_CLEANUP_CRON = "0 * * * * *";
|
static final String DEFAULT_CLEANUP_CRON = "0 * * * * *";
|
||||||
|
|
||||||
@@ -94,12 +96,13 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
|||||||
|
|
||||||
private Executor redisSubscriptionExecutor;
|
private Executor redisSubscriptionExecutor;
|
||||||
|
|
||||||
|
private ClassLoader classLoader;
|
||||||
|
|
||||||
private StringValueResolver embeddedValueResolver;
|
private StringValueResolver embeddedValueResolver;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public RedisOperationsSessionRepository sessionRepository() {
|
public RedisOperationsSessionRepository sessionRepository() {
|
||||||
RedisTemplate<Object, Object> redisTemplate = createRedisTemplate(
|
RedisTemplate<Object, Object> redisTemplate = createRedisTemplate();
|
||||||
this.redisConnectionFactory, this.defaultRedisSerializer);
|
|
||||||
RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(
|
RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(
|
||||||
redisTemplate);
|
redisTemplate);
|
||||||
sessionRepository.setApplicationEventPublisher(this.applicationEventPublisher);
|
sessionRepository.setApplicationEventPublisher(this.applicationEventPublisher);
|
||||||
@@ -205,6 +208,11 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
|||||||
this.redisSubscriptionExecutor = redisSubscriptionExecutor;
|
this.redisSubscriptionExecutor = redisSubscriptionExecutor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||||
|
this.classLoader = classLoader;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEmbeddedValueResolver(StringValueResolver resolver) {
|
public void setEmbeddedValueResolver(StringValueResolver resolver) {
|
||||||
this.embeddedValueResolver = resolver;
|
this.embeddedValueResolver = resolver;
|
||||||
@@ -235,16 +243,15 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
|||||||
this.cleanupCron);
|
this.cleanupCron);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static RedisTemplate<Object, Object> createRedisTemplate(
|
private RedisTemplate<Object, Object> createRedisTemplate() {
|
||||||
RedisConnectionFactory redisConnectionFactory,
|
|
||||||
RedisSerializer<Object> defaultRedisSerializer) {
|
|
||||||
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
|
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
|
||||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||||
if (defaultRedisSerializer != null) {
|
if (this.defaultRedisSerializer != null) {
|
||||||
redisTemplate.setDefaultSerializer(defaultRedisSerializer);
|
redisTemplate.setDefaultSerializer(this.defaultRedisSerializer);
|
||||||
}
|
}
|
||||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
redisTemplate.setConnectionFactory(this.redisConnectionFactory);
|
||||||
|
redisTemplate.setBeanClassLoader(this.classLoader);
|
||||||
redisTemplate.afterPropertiesSet();
|
redisTemplate.afterPropertiesSet();
|
||||||
return redisTemplate;
|
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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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 java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||||
import org.springframework.beans.factory.ObjectProvider;
|
import org.springframework.beans.factory.ObjectProvider;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.EmbeddedValueResolverAware;
|
import org.springframework.context.EmbeddedValueResolverAware;
|
||||||
@@ -53,11 +54,7 @@ import org.springframework.web.server.session.WebSessionManager;
|
|||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
||||||
implements EmbeddedValueResolverAware, ImportAware {
|
implements BeanClassLoaderAware, EmbeddedValueResolverAware, ImportAware {
|
||||||
|
|
||||||
private static final RedisSerializer<String> keySerializer = new StringRedisSerializer();
|
|
||||||
|
|
||||||
private static final RedisSerializer<Object> valueSerializer = new JdkSerializationRedisSerializer();
|
|
||||||
|
|
||||||
private Integer maxInactiveIntervalInSeconds = MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;
|
private Integer maxInactiveIntervalInSeconds = MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;
|
||||||
|
|
||||||
@@ -67,12 +64,15 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
|||||||
|
|
||||||
private ReactiveRedisConnectionFactory redisConnectionFactory;
|
private ReactiveRedisConnectionFactory redisConnectionFactory;
|
||||||
|
|
||||||
|
private ClassLoader classLoader;
|
||||||
|
|
||||||
private StringValueResolver embeddedValueResolver;
|
private StringValueResolver embeddedValueResolver;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public ReactiveRedisOperationsSessionRepository sessionRepository() {
|
public ReactiveRedisOperationsSessionRepository sessionRepository() {
|
||||||
|
ReactiveRedisTemplate<String, Object> reactiveRedisTemplate = createReactiveRedisTemplate();
|
||||||
ReactiveRedisOperationsSessionRepository sessionRepository = new ReactiveRedisOperationsSessionRepository(
|
ReactiveRedisOperationsSessionRepository sessionRepository = new ReactiveRedisOperationsSessionRepository(
|
||||||
createDefaultTemplate(this.redisConnectionFactory));
|
reactiveRedisTemplate);
|
||||||
sessionRepository
|
sessionRepository
|
||||||
.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);
|
.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);
|
||||||
if (StringUtils.hasText(this.redisNamespace)) {
|
if (StringUtils.hasText(this.redisNamespace)) {
|
||||||
@@ -107,6 +107,11 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
|||||||
this.redisConnectionFactory = redisConnectionFactoryToUse;
|
this.redisConnectionFactory = redisConnectionFactoryToUse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||||
|
this.classLoader = classLoader;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEmbeddedValueResolver(StringValueResolver resolver) {
|
public void setEmbeddedValueResolver(StringValueResolver resolver) {
|
||||||
this.embeddedValueResolver = resolver;
|
this.embeddedValueResolver = resolver;
|
||||||
@@ -127,12 +132,15 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
|||||||
this.redisFlushMode = attributes.getEnum("redisFlushMode");
|
this.redisFlushMode = attributes.getEnum("redisFlushMode");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ReactiveRedisTemplate<String, Object> createDefaultTemplate(
|
private ReactiveRedisTemplate<String, Object> createReactiveRedisTemplate() {
|
||||||
ReactiveRedisConnectionFactory connectionFactory) {
|
RedisSerializer<String> keySerializer = new StringRedisSerializer();
|
||||||
|
RedisSerializer<Object> valueSerializer = new JdkSerializationRedisSerializer(
|
||||||
|
this.classLoader);
|
||||||
RedisSerializationContext<String, Object> serializationContext = RedisSerializationContext
|
RedisSerializationContext<String, Object> serializationContext = RedisSerializationContext
|
||||||
.<String, Object>newSerializationContext(valueSerializer)
|
.<String, Object>newSerializationContext(valueSerializer)
|
||||||
.key(keySerializer).hashKey(keySerializer).build();
|
.key(keySerializer).hashKey(keySerializer).build();
|
||||||
return new ReactiveRedisTemplate<>(connectionFactory, serializationContext);
|
return new ReactiveRedisTemplate<>(this.redisConnectionFactory,
|
||||||
|
serializationContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user