JDBC uses Bean ClassLoader

This commit addresses the issue with deserializing JDBC sessions in Spring Boot
applications that use DevTools. Previously, such configuration would cause
`ClassCastException` when deserializing JDBC sessions due to app class loader
being used instead of restart class loader.

Fixes gh-610
This commit is contained in:
Vedran Pavic
2016-09-01 20:52:03 +02:00
committed by Rob Winch
parent 61492c4ae1
commit cbd96999e0

View File

@@ -19,6 +19,7 @@ import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
@@ -26,6 +27,9 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.GenericConversionService;
import org.springframework.core.serializer.support.DeserializingConverter;
import org.springframework.core.serializer.support.SerializingConverter;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.JdbcTemplate;
@@ -52,7 +56,7 @@ import org.springframework.util.StringUtils;
@Configuration
@EnableScheduling
public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
implements ImportAware {
implements BeanClassLoaderAware, ImportAware {
private String tableName;
@@ -66,6 +70,8 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
private ConversionService springSessionConversionService;
private ClassLoader classLoader;
@Bean
public JdbcTemplate springSessionJdbcOperations(DataSource dataSource) {
return new JdbcTemplate(dataSource);
@@ -92,6 +98,14 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
else if (this.conversionService != null) {
sessionRepository.setConversionService(this.conversionService);
}
else if (this.classLoader != null) {
GenericConversionService conversionService = new GenericConversionService();
conversionService.addConverter(Object.class, byte[].class,
new SerializingConverter());
conversionService.addConverter(byte[].class, Object.class,
new DeserializingConverter(this.classLoader));
sessionRepository.setConversionService(conversionService);
}
return sessionRepository;
}
@@ -123,6 +137,16 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
return this.tableName;
}
public void setBeanClassLoader(ClassLoader classLoader) {
try {
DeserializingConverter.class.getConstructor(ClassLoader.class);
}
catch (NoSuchMethodException e) {
return;
}
this.classLoader = classLoader;
}
public void setImportMetadata(AnnotationMetadata importMetadata) {
Map<String, Object> enableAttrMap = importMetadata
.getAnnotationAttributes(EnableJdbcHttpSession.class.getName());