diff --git a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java index 302510a90..2e5214eba 100644 --- a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java +++ b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java @@ -18,6 +18,7 @@ package org.springframework.data.repository.core.support; import java.io.Serializable; import java.util.List; +import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Required; @@ -41,7 +42,7 @@ import org.springframework.util.Assert; * @author Oliver Gierke */ public abstract class RepositoryFactoryBeanSupport, S, ID extends Serializable> implements - InitializingBean, RepositoryFactoryInformation, FactoryBean { + InitializingBean, RepositoryFactoryInformation, FactoryBean, BeanClassLoaderAware { private RepositoryFactorySupport factory; @@ -50,6 +51,7 @@ public abstract class RepositoryFactoryBeanSupport, private Object customImplementation; private NamedQueries namedQueries; private MappingContext mappingContext; + private ClassLoader classLoader; /** * Setter to inject the repository interface to implement. @@ -69,7 +71,6 @@ public abstract class RepositoryFactoryBeanSupport, * @param queryLookupStrategyKey */ public void setQueryLookupStrategyKey(Key queryLookupStrategyKey) { - this.queryLookupStrategyKey = queryLookupStrategyKey; } @@ -79,7 +80,6 @@ public abstract class RepositoryFactoryBeanSupport, * @param customImplementation */ public void setCustomImplementation(Object customImplementation) { - this.customImplementation = customImplementation; } @@ -102,6 +102,15 @@ public abstract class RepositoryFactoryBeanSupport, this.mappingContext = mappingContext; } + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(java.lang.ClassLoader) + */ + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + /* * (non-Javadoc) * @see org.springframework.data.repository.core.support.RepositoryFactoryInformation#getEntityInformation() @@ -179,6 +188,7 @@ public abstract class RepositoryFactoryBeanSupport, this.factory = createRepositoryFactory(); this.factory.setQueryLookupStrategyKey(queryLookupStrategyKey); this.factory.setNamedQueries(namedQueries); + this.factory.setBeanClassLoader(classLoader); } /** diff --git a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java index 305142b3c..72d1f4ad3 100644 --- a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java +++ b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java @@ -27,6 +27,7 @@ import java.util.concurrent.ConcurrentHashMap; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.framework.ProxyFactory; +import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.core.GenericTypeResolver; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.EntityInformation; @@ -47,12 +48,13 @@ import org.springframework.util.Assert; * * @author Oliver Gierke */ -public abstract class RepositoryFactorySupport { +public abstract class RepositoryFactorySupport implements BeanClassLoaderAware { private final List postProcessors = new ArrayList(); private QueryLookupStrategy.Key queryLookupStrategyKey; private List> queryPostProcessors = new ArrayList>(); private NamedQueries namedQueries = PropertiesBasedNamedQueries.EMPTY; + private ClassLoader classLoader = org.springframework.util.ClassUtils.getDefaultClassLoader(); private QueryCollectingQueryCreationListener collectingListener = new QueryCollectingQueryCreationListener(); @@ -78,6 +80,15 @@ public abstract class RepositoryFactorySupport { this.namedQueries = namedQueries == null ? PropertiesBasedNamedQueries.EMPTY : namedQueries; } + /* + * (non-Javadoc) + * @see org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(java.lang.ClassLoader) + */ + @Override + public void setBeanClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader == null ? org.springframework.util.ClassUtils.getDefaultClassLoader() : classLoader; + } + /** * Adds a {@link QueryCreationListener} to the factory to plug in functionality triggered right after creation of * {@link RepositoryQuery} instances. @@ -146,7 +157,7 @@ public abstract class RepositoryFactorySupport { result.addAdvice(new QueryExecutorMethodInterceptor(information, customImplementation, target)); - return (T) result.getProxy(); + return (T) result.getProxy(classLoader); } /** diff --git a/src/test/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupportUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupportUnitTests.java new file mode 100644 index 000000000..fa39038b6 --- /dev/null +++ b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupportUnitTests.java @@ -0,0 +1,48 @@ +/* + * Copyright 2013 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.data.repository.core.support; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +import org.junit.Test; +import org.springframework.test.util.ReflectionTestUtils; + +/** + * Unit tests for {@link RepositoryFactoryBeanSupport}. + * + * @author Oliver Gierke + */ +public class RepositoryFactoryBeanSupportUnitTests { + + /** + * @see DATACMNS-341 + */ + @Test + @SuppressWarnings("rawtypes") + public void setsConfiguredClassLoaderOnRepositoryFactory() { + + ClassLoader classLoader = mock(ClassLoader.class); + + RepositoryFactoryBeanSupport factoryBean = new DummyRepositoryFactoryBean(); + factoryBean.setBeanClassLoader(classLoader); + factoryBean.afterPropertiesSet(); + + Object factory = ReflectionTestUtils.getField(factoryBean, "factory"); + assertThat(ReflectionTestUtils.getField(factory, "classLoader"), is((Object) classLoader)); + } +} diff --git a/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java index 17da693fa..364e6f252 100644 --- a/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactorySupportUnitTests.java @@ -36,6 +36,8 @@ import org.springframework.data.repository.PagingAndSortingRepository; import org.springframework.data.repository.Repository; import org.springframework.data.repository.RepositoryDefinition; import org.springframework.data.repository.query.RepositoryQuery; +import org.springframework.test.util.ReflectionTestUtils; +import org.springframework.util.ClassUtils; /** * Unit tests for {@link RepositoryFactorySupport}. @@ -47,15 +49,11 @@ public class RepositoryFactorySupportUnitTests { RepositoryFactorySupport factory; - @Mock - PagingAndSortingRepository backingRepo; - @Mock - ObjectRepositoryCustom customImplementation; + @Mock PagingAndSortingRepository backingRepo; + @Mock ObjectRepositoryCustom customImplementation; - @Mock - MyQueryCreationListener listener; - @Mock - PlainQueryCreationListener otherListener; + @Mock MyQueryCreationListener listener; + @Mock PlainQueryCreationListener otherListener; @Before public void setUp() { @@ -113,6 +111,16 @@ public class RepositoryFactorySupportUnitTests { assertThat(factory.getRepository(foo), is(notNullValue())); } + /** + * @see DATACMNS-341 + */ + @Test + public void usesDefaultClassLoaderIfNullConfigured() { + + factory.setBeanClassLoader(null); + assertThat(ReflectionTestUtils.getField(factory, "classLoader"), is((Object) ClassUtils.getDefaultClassLoader())); + } + interface ObjectRepository extends Repository, ObjectRepositoryCustom { Object findByClass(Class clazz);