Skip to content

Commit 79b4028

Browse files
DATAREDIS-501 - Use application context ClassLoader as default for JdkSerializationRedisSerializer in RedisTemplate.
We now pick up the ResourceLoader 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.
1 parent a3bd816 commit 79b4028

File tree

2 files changed

+63
-6
lines changed

2 files changed

+63
-6
lines changed

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

Lines changed: 27 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,8 @@
2626
import java.util.Set;
2727
import java.util.concurrent.TimeUnit;
2828

29+
import org.springframework.context.ResourceLoaderAware;
30+
import org.springframework.core.io.ResourceLoader;
2931
import org.springframework.dao.DataAccessException;
3032
import org.springframework.dao.InvalidDataAccessApiUsageException;
3133
import org.springframework.data.redis.RedisSystemException;
@@ -75,13 +77,14 @@
7577
* @param <V> the Redis value type against which the template works
7678
* @see StringRedisTemplate
7779
*/
78-
public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V> {
80+
public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperations<K, V>, ResourceLoaderAware {
7981

8082
private boolean enableTransactionSupport = false;
8183
private boolean exposeConnection = false;
8284
private boolean initialized = false;
8385
private boolean enableDefaultSerializer = true;
84-
private RedisSerializer<?> defaultSerializer = new JdkSerializationRedisSerializer();
86+
private RedisSerializer<?> defaultSerializer;
87+
private ResourceLoader resourceLoader;
8588

8689
private RedisSerializer keySerializer = null;
8790
private RedisSerializer valueSerializer = null;
@@ -104,10 +107,18 @@ public class RedisTemplate<K, V> extends RedisAccessor implements RedisOperation
104107
public RedisTemplate() {}
105108

106109
public void afterPropertiesSet() {
110+
107111
super.afterPropertiesSet();
112+
108113
boolean defaultUsed = false;
109114

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

1110+
/**
1111+
* Set the {@link ResourceLoader} 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.context.ResourceLoaderAware#setResourceLoader
1116+
* @since 1.8
1117+
*/
1118+
@Override
1119+
public void setResourceLoader(ResourceLoader resourceLoader) {
1120+
this.resourceLoader = resourceLoader;
1121+
}
1122+
10991123
}

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

Lines changed: 36 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,39 @@
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;
31+
import org.springframework.core.io.DefaultResourceLoader;
2632
import org.springframework.data.redis.connection.RedisConnection;
2733
import org.springframework.data.redis.connection.RedisConnectionFactory;
34+
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
35+
import org.springframework.instrument.classloading.ShadowingClassLoader;
2836

2937
/**
3038
* @author Christoph Strobl
3139
*/
3240
@RunWith(MockitoJUnitRunner.class)
3341
public class RedisTemplateUnitTests {
3442

35-
private RedisTemplate<String, String> template;
43+
private RedisTemplate<Object, Object> template;
3644
private @Mock RedisConnectionFactory connectionFactoryMock;
3745
private @Mock RedisConnection redisConnectionMock;
3846

3947
@Before
4048
public void setUp() {
4149

42-
template = new RedisTemplate<String, String>();
50+
template = new RedisTemplate<Object, Object>();
4351
template.setConnectionFactory(connectionFactoryMock);
4452
when(connectionFactoryMock.getConnection()).thenReturn(redisConnectionMock);
4553

@@ -66,4 +74,29 @@ public void slaveOfNoOneIsDelegatedToConnectionCorrectly() {
6674
verify(redisConnectionMock, times(1)).slaveOfNoOne();
6775
}
6876

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

0 commit comments

Comments
 (0)