Skip to content

Commit f173a6f

Browse files
committed
DATAJPA-871 - CrudMethodMetadataPostProcessor now uses the bean ClassLoader.
The thread-local proxy for the CrudMethodMetadata is now created using the bean ClassLoader, which the repository factory gets set from the container. Renamed the property for the post processor and its lookup method.
1 parent e81bb98 commit f173a6f

File tree

3 files changed

+47
-8
lines changed

3 files changed

+47
-8
lines changed

src/main/java/org/springframework/data/jpa/repository/support/CrudMethodMetadataPostProcessor.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.springframework.aop.framework.ProxyFactory;
3131
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
3232
import org.springframework.aop.target.AbstractLazyCreationTargetSource;
33+
import org.springframework.beans.factory.BeanClassLoaderAware;
3334
import org.springframework.core.annotation.AnnotationUtils;
3435
import org.springframework.data.jpa.repository.EntityGraph;
3536
import org.springframework.data.jpa.repository.Lock;
@@ -39,6 +40,7 @@
3940
import org.springframework.data.repository.core.support.RepositoryProxyPostProcessor;
4041
import org.springframework.transaction.support.TransactionSynchronizationManager;
4142
import org.springframework.util.Assert;
43+
import org.springframework.util.ClassUtils;
4244

4345
/**
4446
* {@link RepositoryProxyPostProcessor} that sets up interceptors to read metadata information from the invoked method.
@@ -48,9 +50,19 @@
4850
* @author Oliver Gierke
4951
* @author Thomas Darimont
5052
*/
51-
enum CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor {
53+
class CrudMethodMetadataPostProcessor implements RepositoryProxyPostProcessor, BeanClassLoaderAware {
5254

53-
INSTANCE;
55+
private ClassLoader classLoader = ClassUtils.getDefaultClassLoader();
56+
57+
/*
58+
* (non-Javadoc)
59+
* @see org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(java.lang.ClassLoader)
60+
*/
61+
@Override
62+
public void setBeanClassLoader(ClassLoader classLoader) {
63+
this.classLoader = classLoader == null ? ClassUtils.getDefaultClassLoader() : classLoader;
64+
65+
}
5466

5567
/*
5668
* (non-Javadoc)
@@ -65,14 +77,14 @@ public void postProcess(ProxyFactory factory, RepositoryInformation repositoryIn
6577
* Returns a {@link CrudMethodMetadata} proxy that will lookup the actual target object by obtaining a thread bound
6678
* instance from the {@link TransactionSynchronizationManager} later.
6779
*/
68-
public CrudMethodMetadata getLockMetadataProvider() {
80+
public CrudMethodMetadata getCrudMethodMetadata() {
6981

7082
ProxyFactory factory = new ProxyFactory();
7183

7284
factory.addInterface(CrudMethodMetadata.class);
7385
factory.setTargetSource(new ThreadBoundTargetSource());
7486

75-
return (CrudMethodMetadata) factory.getProxy();
87+
return (CrudMethodMetadata) factory.getProxy(this.classLoader);
7688
}
7789

7890
/**

src/main/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactory.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public class JpaRepositoryFactory extends RepositoryFactorySupport {
4242

4343
private final EntityManager entityManager;
4444
private final QueryExtractor extractor;
45-
private final CrudMethodMetadataPostProcessor lockModePostProcessor;
45+
private final CrudMethodMetadataPostProcessor crudMethodMetadataPostProcessor;
4646

4747
/**
4848
* Creates a new {@link JpaRepositoryFactory}.
@@ -55,9 +55,19 @@ public JpaRepositoryFactory(EntityManager entityManager) {
5555

5656
this.entityManager = entityManager;
5757
this.extractor = PersistenceProvider.fromEntityManager(entityManager);
58-
this.lockModePostProcessor = CrudMethodMetadataPostProcessor.INSTANCE;
58+
this.crudMethodMetadataPostProcessor = new CrudMethodMetadataPostProcessor();
5959

60-
addRepositoryProxyPostProcessor(lockModePostProcessor);
60+
addRepositoryProxyPostProcessor(crudMethodMetadataPostProcessor);
61+
}
62+
63+
/*
64+
* (non-Javadoc)
65+
* @see org.springframework.data.repository.core.support.RepositoryFactorySupport#setBeanClassLoader(java.lang.ClassLoader)
66+
*/
67+
@Override
68+
public void setBeanClassLoader(ClassLoader classLoader) {
69+
super.setBeanClassLoader(classLoader);
70+
this.crudMethodMetadataPostProcessor.setBeanClassLoader(classLoader);
6171
}
6272

6373
/*
@@ -68,7 +78,7 @@ public JpaRepositoryFactory(EntityManager entityManager) {
6878
protected Object getTargetRepository(RepositoryMetadata metadata) {
6979

7080
SimpleJpaRepository<?, ?> repository = getTargetRepository(metadata, entityManager);
71-
repository.setRepositoryMethodMetadata(lockModePostProcessor.getLockMetadataProvider());
81+
repository.setRepositoryMethodMetadata(crudMethodMetadataPostProcessor.getCrudMethodMetadata());
7282

7383
return repository;
7484
}

src/test/java/org/springframework/data/jpa/repository/support/JpaRepositoryFactoryUnitTests.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,17 @@
3131
import org.mockito.Mock;
3232
import org.mockito.runners.MockitoJUnitRunner;
3333
import org.springframework.aop.framework.Advised;
34+
import org.springframework.core.OverridingClassLoader;
3435
import org.springframework.data.jpa.domain.sample.User;
3536
import org.springframework.data.jpa.repository.JpaRepository;
3637
import org.springframework.data.jpa.repository.custom.CustomGenericJpaRepositoryFactory;
3738
import org.springframework.data.jpa.repository.custom.UserCustomExtendedRepository;
3839
import org.springframework.data.querydsl.QueryDslPredicateExecutor;
3940
import org.springframework.data.repository.core.support.DefaultRepositoryMetadata;
4041
import org.springframework.data.repository.query.QueryLookupStrategy.Key;
42+
import org.springframework.test.util.ReflectionTestUtils;
4143
import org.springframework.transaction.annotation.Transactional;
44+
import org.springframework.util.ClassUtils;
4245

4346
/**
4447
* Unit test for {@code JpaRepositoryFactory}.
@@ -152,6 +155,20 @@ public void usesQueryDslRepositoryIfInterfaceImplementsExecutor() {
152155
}
153156
}
154157

158+
/**
159+
* @see DATAJPA-819
160+
*/
161+
@Test
162+
public void crudMethodMetadataPostProcessorUsesBeanClassLoader() {
163+
164+
ClassLoader classLoader = new OverridingClassLoader(ClassUtils.getDefaultClassLoader());
165+
166+
factory.setBeanClassLoader(classLoader);
167+
168+
Object processor = ReflectionTestUtils.getField(factory, "crudMethodMetadataPostProcessor");
169+
assertThat(ReflectionTestUtils.getField(processor, "classLoader"), is((Object) classLoader));
170+
}
171+
155172
private interface SimpleSampleRepository extends JpaRepository<User, Integer> {
156173

157174
@Transactional

0 commit comments

Comments
 (0)