Skip to content

Commit 0f8969f

Browse files
christophstroblmp911de
authored andcommitted
DATAREDIS-501 - Use application context ClassLoader as default for JdkSerializationRedisSerializer in RedisTemplate.
We now pick up the ClassLoader from the ApplicationContext and use the latter as default in RedisTemplate for initializing the JdkSerializationRedisSerializer. We only do this in case the default serializer has not been set explicitly. Original pull request: #192.
1 parent d27980a commit 0f8969f

File tree

2 files changed

+61
-6
lines changed

2 files changed

+61
-6
lines changed

src/main/java/org/springframework/data/redis/core/RedisTemplate.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2011-2015 the original author or authors.
2+
* Copyright 2011-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
2626
import java.util.Set;
2727
import java.util.concurrent.TimeUnit;
2828

29+
import org.springframework.beans.factory.BeanClassLoaderAware;
2930
import org.springframework.dao.DataAccessException;
3031
import org.springframework.dao.InvalidDataAccessApiUsageException;
3132
import org.springframework.data.redis.RedisSystemException;
@@ -75,13 +76,14 @@
7576
* @param <V> the Redis value type against which the template works
7677
* @see StringRedisTemplate
7778
*/
78-
public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V> {
79+
public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, BeanClassLoaderAware {
7980

8081
private boolean enableTransactionSupport = false;
8182
private boolean exposeConnection = false;
8283
private boolean initialized = false;
8384
private boolean enableDefaultSerializer = true;
84-
private RedisSerializer<?> defaultSerializer = new JdkSerializationRedisSerializer();
85+
private RedisSerializer<?> defaultSerializer;
86+
private ClassLoader classLoader;
8587

8688
private RedisSerializer keySerializer = null;
8789
private RedisSerializer valueSerializer = null;
@@ -104,10 +106,19 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
104106
public RedisTemplate() {}
105107

106108
public void afterPropertiesSet() {
109+
107110
super.afterPropertiesSet();
111+
108112
boolean defaultUsed = false;
109113

114+
if (defaultSerializer == null) {
115+
116+
defaultSerializer = new JdkSerializationRedisSerializer(
117+
classLoader != null ? classLoader : this.getClass().getClassLoader());
118+
}
119+
110120
if (enableDefaultSerializer) {
121+
111122
if (keySerializer == null) {
112123
keySerializer = defaultSerializer;
113124
defaultUsed = true;
@@ -1096,4 +1107,16 @@ public void setEnableTransactionSupport(boolean enableTransactionSupport) {
10961107
this.enableTransactionSupport = enableTransactionSupport;
10971108
}
10981109

1110+
/**
1111+
* Set the {@link ClassLoader} to be used for the default {@link JdkSerializationRedisSerializer} in case no other
1112+
* {@link RedisSerializer} is explicitly set as the default one.
1113+
*
1114+
* @param resourceLoader can be {@literal null}.
1115+
* @see org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader
1116+
* @since 1.7.2
1117+
*/
1118+
@Override
1119+
public void setBeanClassLoader(ClassLoader classLoader) {
1120+
this.classLoader = classLoader;
1121+
}
10991122
}

src/test/java/org/springframework/data/redis/core/RedisTemplateUnitTests.java

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2014 the original author or authors.
2+
* Copyright 2014-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,31 +15,38 @@
1515
*/
1616
package org.springframework.data.redis.core;
1717

18+
import static org.hamcrest.core.Is.*;
19+
import static org.hamcrest.core.IsNull.*;
20+
import static org.junit.Assert.*;
1821
import static org.mockito.Matchers.*;
1922
import static org.mockito.Mockito.*;
2023

24+
import java.io.Serializable;
25+
2126
import org.junit.Before;
2227
import org.junit.Test;
2328
import org.junit.runner.RunWith;
2429
import org.mockito.Mock;
2530
import org.mockito.runners.MockitoJUnitRunner;
2631
import org.springframework.data.redis.connection.RedisConnection;
2732
import org.springframework.data.redis.connection.RedisConnectionFactory;
33+
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
34+
import org.springframework.instrument.classloading.ShadowingClassLoader;
2835

2936
/**
3037
* @author Christoph Strobl
3138
*/
3239
@RunWith(MockitoJUnitRunner.class)
3340
public class RedisTemplateUnitTests {
3441

35-
private RedisTemplate<String, String> template;
42+
private RedisTemplate<Object, Object> template;
3643
private @Mock RedisConnectionFactory connectionFactoryMock;
3744
private @Mock RedisConnection redisConnectionMock;
3845

3946
@Before
4047
public void setUp() {
4148

42-
template = new RedisTemplate<String, String>();
49+
template = new RedisTemplate<Object, Object>();
4350
template.setConnectionFactory(connectionFactoryMock);
4451
when(connectionFactoryMock.getConnection()).thenReturn(redisConnectionMock);
4552

@@ -66,4 +73,29 @@ public void slaveOfNoOneIsDelegatedToConnectionCorrectly() {
6673
verify(redisConnectionMock, times(1)).slaveOfNoOne();
6774
}
6875

76+
/**
77+
* @see DATAREDIS-501
78+
*/
79+
@Test
80+
public void templateShouldPassOnAndUseResoureLoaderClassLoaderToDefaultJdkSerializerWhenNotAlreadySet() {
81+
82+
ShadowingClassLoader scl = new ShadowingClassLoader(ClassLoader.getSystemClassLoader());
83+
84+
template = new RedisTemplate<Object, Object>();
85+
template.setConnectionFactory(connectionFactoryMock);
86+
template.setBeanClassLoader(scl);
87+
template.afterPropertiesSet();
88+
89+
when(redisConnectionMock.get(any(byte[].class)))
90+
.thenReturn(new JdkSerializationRedisSerializer().serialize(new SomeArbitrarySeriaizableObject()));
91+
92+
Object deserialized = template.opsForValue().get("spring");
93+
assertThat(deserialized, notNullValue());
94+
assertThat(deserialized.getClass().getClassLoader(), is((ClassLoader) scl));
95+
}
96+
97+
static class SomeArbitrarySeriaizableObject implements Serializable {
98+
private static final long serialVersionUID = -5973659324040506423L;
99+
}
100+
69101
}

0 commit comments

Comments
 (0)