Remove redundant restart-compatible Redis serializer
Previously, Spring Data Redis assumed that the class loader that loaded its classes would also be able to load the application’s classes. This assumption is faulty when there are multiple class loaders involved such as when using dev tools or when Spring Data Redis is installed as a shared library in a servlet container. DATAREDIS-427 and DATAREDIS-501 removed this assumption by making the default serialiser use the bean class loader. DevTools configures this class loader to be the restart class loader which can load the application’s classes. As a result of moving to Hopper SR2 snapshots, these fixes are now available and we can remove our custom serialised. Closes gh-5760
This commit is contained in:
parent
1b252c3e82
commit
d839e1ec00
|
|
@ -21,9 +21,7 @@ import java.net.URL;
|
|||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
|
|
@ -42,7 +40,6 @@ import org.springframework.context.annotation.Bean;
|
|||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
|
|
@ -164,21 +161,6 @@ public class LocalDevToolsAutoConfiguration {
|
|||
return watcher;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnBean(name = RedisRestartConfiguration.SESSION_REDIS_TEMPLATE_BEAN_NAME)
|
||||
static class RedisRestartConfiguration {
|
||||
|
||||
static final String SESSION_REDIS_TEMPLATE_BEAN_NAME = "sessionRedisTemplate";
|
||||
|
||||
@Bean
|
||||
public RestartCompatibleRedisSerializerConfigurer restartCompatibleRedisSerializerConfigurer(
|
||||
@Qualifier(SESSION_REDIS_TEMPLATE_BEAN_NAME) RedisTemplate<?, ?> sessionRedisTemplate) {
|
||||
return new RestartCompatibleRedisSerializerConfigurer(
|
||||
sessionRedisTemplate);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012-2016 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.devtools.autoconfigure;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.serializer.DefaultDeserializer;
|
||||
import org.springframework.core.serializer.support.DeserializingConverter;
|
||||
import org.springframework.core.serializer.support.SerializingConverter;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.data.redis.serializer.SerializationException;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
|
||||
/**
|
||||
* Configures a {@link RedisTemplate} with a serializer for keys, values, hash keys, and
|
||||
* hash values that is compatible with the split classloader used for restarts.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Rob Winch
|
||||
* @see RedisTemplate#setHashKeySerializer(RedisSerializer)
|
||||
* @see RedisTemplate#setHashValueSerializer(RedisSerializer)
|
||||
* @see RedisTemplate#setKeySerializer(RedisSerializer)
|
||||
* @see RedisTemplate#setValueSerializer(RedisSerializer)
|
||||
*/
|
||||
class RestartCompatibleRedisSerializerConfigurer implements BeanClassLoaderAware {
|
||||
|
||||
private final RedisTemplate<?, ?> redisTemplate;
|
||||
|
||||
private volatile ClassLoader classLoader;
|
||||
|
||||
RestartCompatibleRedisSerializerConfigurer(RedisTemplate<?, ?> redisTemplate) {
|
||||
this.redisTemplate = redisTemplate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
void configureTemplateSerializers() {
|
||||
RestartCompatibleRedisSerializer serializer = new RestartCompatibleRedisSerializer(
|
||||
this.classLoader);
|
||||
this.redisTemplate.setHashKeySerializer(serializer);
|
||||
this.redisTemplate.setHashValueSerializer(serializer);
|
||||
this.redisTemplate.setKeySerializer(serializer);
|
||||
this.redisTemplate.setValueSerializer(serializer);
|
||||
}
|
||||
|
||||
static class RestartCompatibleRedisSerializer implements RedisSerializer<Object> {
|
||||
|
||||
private static final byte[] NO_BYTES = new byte[0];
|
||||
|
||||
private final Converter<Object, byte[]> serializer = new SerializingConverter();
|
||||
|
||||
private final Converter<byte[], Object> deserializer;
|
||||
|
||||
RestartCompatibleRedisSerializer(ClassLoader classLoader) {
|
||||
this.deserializer = new DeserializingConverter(
|
||||
new DefaultDeserializer(classLoader));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object deserialize(byte[] bytes) {
|
||||
try {
|
||||
return (ObjectUtils.isEmpty(bytes) ? null
|
||||
: this.deserializer.convert(bytes));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new SerializationException("Cannot deserialize", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] serialize(Object object) {
|
||||
try {
|
||||
return (object == null ? NO_BYTES : this.serializer.convert(object));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new SerializationException("Cannot serialize", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -31,7 +31,6 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
|||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.web.ResourceProperties;
|
||||
import org.springframework.boot.devtools.autoconfigure.RestartCompatibleRedisSerializerConfigurer.RestartCompatibleRedisSerializer;
|
||||
import org.springframework.boot.devtools.classpath.ClassPathChangedEvent;
|
||||
import org.springframework.boot.devtools.classpath.ClassPathFileSystemWatcher;
|
||||
import org.springframework.boot.devtools.filewatch.ChangedFiles;
|
||||
|
|
@ -235,31 +234,6 @@ public class LocalDevToolsAutoConfigurationTests {
|
|||
.containsKey(new File("src/test/java").getAbsoluteFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionRedisTemplateIsConfiguredWithCustomDeserializers()
|
||||
throws Exception {
|
||||
sessionRedisTemplateIsConfiguredWithCustomDeserializers(
|
||||
SessionRedisTemplateConfig.class);
|
||||
}
|
||||
|
||||
private void sessionRedisTemplateIsConfiguredWithCustomDeserializers(
|
||||
Object sessionConfig) throws Exception {
|
||||
SpringApplication application = new SpringApplication(sessionConfig,
|
||||
LocalDevToolsAutoConfiguration.class);
|
||||
application.setWebEnvironment(false);
|
||||
this.context = application.run();
|
||||
RedisTemplate<?, ?> redisTemplate = this.context.getBean("sessionRedisTemplate",
|
||||
RedisTemplate.class);
|
||||
assertThat(redisTemplate.getHashKeySerializer())
|
||||
.isInstanceOf(RestartCompatibleRedisSerializer.class);
|
||||
assertThat(redisTemplate.getHashValueSerializer())
|
||||
.isInstanceOf(RestartCompatibleRedisSerializer.class);
|
||||
assertThat(redisTemplate.getKeySerializer())
|
||||
.isInstanceOf(RestartCompatibleRedisSerializer.class);
|
||||
assertThat(redisTemplate.getValueSerializer())
|
||||
.isInstanceOf(RestartCompatibleRedisSerializer.class);
|
||||
}
|
||||
|
||||
private ConfigurableApplicationContext initializeAndRun(Class<?> config,
|
||||
String... args) {
|
||||
return initializeAndRun(config, Collections.<String, Object>emptyMap(), args);
|
||||
|
|
|
|||
Loading…
Reference in New Issue