Skip to content

Commit f9d5369

Browse files
xeounxzxump911de
authored andcommitted
Avoid multiple DeferredRepositoryInitializationListener registrations in RepositoryConfigurationDelegate.
Closes #3287 Original pull request: #3219
1 parent 4ea9405 commit f9d5369

File tree

2 files changed

+39
-32
lines changed

2 files changed

+39
-32
lines changed

src/main/java/org/springframework/data/repository/config/RepositoryConfigurationDelegate.java

+14-23
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,13 @@
1515
*/
1616
package org.springframework.data.repository.config;
1717

18-
import java.lang.reflect.TypeVariable;
19-
import java.util.ArrayList;
20-
import java.util.Arrays;
21-
import java.util.Collection;
22-
import java.util.HashMap;
23-
import java.util.List;
24-
import java.util.Map;
25-
import java.util.stream.Collectors;
26-
2718
import org.apache.commons.logging.Log;
2819
import org.apache.commons.logging.LogFactory;
29-
3020
import org.springframework.beans.factory.config.BeanDefinition;
3121
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
3222
import org.springframework.beans.factory.config.DependencyDescriptor;
3323
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
34-
import org.springframework.beans.factory.support.AutowireCandidateResolver;
35-
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
36-
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
37-
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
38-
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
39-
import org.springframework.beans.factory.support.RootBeanDefinition;
24+
import org.springframework.beans.factory.support.*;
4025
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
4126
import org.springframework.context.support.GenericApplicationContext;
4227
import org.springframework.core.ResolvableType;
@@ -57,6 +42,10 @@
5742
import org.springframework.util.Assert;
5843
import org.springframework.util.StopWatch;
5944

45+
import java.lang.reflect.TypeVariable;
46+
import java.util.*;
47+
import java.util.stream.Collectors;
48+
6049
/**
6150
* Delegate for configuration integration to reuse the general way of detecting repositories. Customization is done by
6251
* providing a configuration format specific {@link RepositoryConfigurationSource} (currently either XML or annotations
@@ -92,7 +81,7 @@ public class RepositoryConfigurationDelegate {
9281
* @param environment must not be {@literal null}.
9382
*/
9483
public RepositoryConfigurationDelegate(RepositoryConfigurationSource configurationSource,
95-
ResourceLoader resourceLoader, Environment environment) {
84+
ResourceLoader resourceLoader, Environment environment) {
9685

9786
this.isXml = configurationSource instanceof XmlRepositoryConfigurationSource;
9887
boolean isAnnotation = configurationSource instanceof AnnotationRepositoryConfigurationSource;
@@ -117,7 +106,7 @@ public RepositoryConfigurationDelegate(RepositoryConfigurationSource configurati
117106
* {@link Environment}.
118107
*/
119108
private static Environment defaultEnvironment(@Nullable Environment environment,
120-
@Nullable ResourceLoader resourceLoader) {
109+
@Nullable ResourceLoader resourceLoader) {
121110

122111
if (environment != null) {
123112
return environment;
@@ -136,7 +125,7 @@ private static Environment defaultEnvironment(@Nullable Environment environment,
136125
* @see org.springframework.beans.factory.support.BeanDefinitionRegistry
137126
*/
138127
public List<BeanComponentDefinition> registerRepositoriesIn(BeanDefinitionRegistry registry,
139-
RepositoryConfigurationExtension extension) {
128+
RepositoryConfigurationExtension extension) {
140129

141130
if (logger.isInfoEnabled()) {
142131
logger.info(LogMessage.format("Bootstrapping Spring Data %s repositories in %s mode.", //
@@ -222,7 +211,7 @@ public List<BeanComponentDefinition> registerRepositoriesIn(BeanDefinitionRegist
222211
}
223212

224213
private void registerAotComponents(BeanDefinitionRegistry registry, RepositoryConfigurationExtension extension,
225-
Map<String, RepositoryConfigurationAdapter<?>> metadataByRepositoryBeanName) {
214+
Map<String, RepositoryConfigurationAdapter<?>> metadataByRepositoryBeanName) {
226215

227216
BeanDefinitionBuilder repositoryAotProcessor = BeanDefinitionBuilder
228217
.rootBeanDefinition(extension.getRepositoryAotProcessor()).setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
@@ -245,7 +234,7 @@ private void registerAotComponents(BeanDefinitionRegistry registry, RepositoryCo
245234
* @param registry must not be {@literal null}.
246235
*/
247236
private static void potentiallyLazifyRepositories(Map<String, RepositoryConfiguration<?>> configurations,
248-
BeanDefinitionRegistry registry, BootstrapMode mode) {
237+
BeanDefinitionRegistry registry, BootstrapMode mode) {
249238

250239
if (!DefaultListableBeanFactory.class.isInstance(registry) || BootstrapMode.DEFAULT.equals(mode)) {
251240
return;
@@ -272,8 +261,10 @@ private static void potentiallyLazifyRepositories(Map<String, RepositoryConfigur
272261

273262
logger.debug("Registering deferred repository initialization listener.");
274263

275-
beanFactory.registerSingleton(DeferredRepositoryInitializationListener.class.getName(),
276-
new DeferredRepositoryInitializationListener(beanFactory));
264+
if (!beanFactory.containsBean(DeferredRepositoryInitializationListener.class.getName())) {
265+
beanFactory.registerSingleton(DeferredRepositoryInitializationListener.class.getName(),
266+
new DeferredRepositoryInitializationListener(beanFactory));
267+
}
277268
}
278269
}
279270

src/test/java/org/springframework/data/repository/config/RepositoryConfigurationDelegateUnitTests.java

+25-9
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,6 @@
1515
*/
1616
package org.springframework.data.repository.config;
1717

18-
import static org.assertj.core.api.Assertions.*;
19-
20-
import java.lang.reflect.TypeVariable;
21-
import java.util.List;
22-
import java.util.Optional;
23-
import java.util.UUID;
24-
2518
import org.junit.jupiter.api.Test;
2619
import org.junit.jupiter.api.extension.ExtendWith;
2720
import org.mockito.Mockito;
@@ -59,11 +52,19 @@
5952
import org.springframework.data.repository.sample.AddressRepositoryClient;
6053
import org.springframework.data.repository.sample.ProductRepository;
6154

55+
import java.lang.reflect.TypeVariable;
56+
import java.util.List;
57+
import java.util.Optional;
58+
import java.util.UUID;
59+
60+
import static org.assertj.core.api.Assertions.assertThat;
61+
6262
/**
6363
* Unit tests for {@link RepositoryConfigurationDelegate}.
6464
*
6565
* @author Oliver Gierke
6666
* @author Mark Paluch
67+
* @author xeounxzxu
6768
* @soundtrack Richard Spaven - Tribute (Whole Other*)
6869
*/
6970
@ExtendWith(MockitoExtension.class)
@@ -109,7 +110,16 @@ void registersDeferredRepositoryInitializationListener() {
109110
var beanFactory = assertLazyRepositoryBeanSetup(DeferredConfig.class);
110111

111112
assertThat(beanFactory.getBeanNamesForType(DeferredRepositoryInitializationListener.class)).isNotEmpty();
113+
}
114+
115+
@Test
116+
void registersMultiDeferredRepositoryInitializationListener() {
117+
118+
var beanFactory = assertLazyRepositoryBeanSetup(DeferredConfig.class, OtherDeferredConfig.class);
112119

120+
assertThat(beanFactory.getBeanNamesForType(DeferredRepositoryInitializationListener.class)).isNotEmpty();
121+
assertThat(beanFactory.getBeanNamesForType(AddressRepository.class)).isNotEmpty();
122+
assertThat(beanFactory.getBeanNamesForType(ProductRepository.class)).isNotEmpty();
113123
}
114124

115125
@Test // DATACMNS-1832
@@ -276,9 +286,9 @@ void considersGenericLength() {
276286
assertThat(it.getGeneric(1).resolve()).isEqualTo(Person.class);
277287
}
278288

279-
private static ListableBeanFactory assertLazyRepositoryBeanSetup(Class<?> configClass) {
289+
private static ListableBeanFactory assertLazyRepositoryBeanSetup(Class<?>... componentClasses) {
280290

281-
var context = new AnnotationConfigApplicationContext(configClass);
291+
var context = new AnnotationConfigApplicationContext(componentClasses);
282292

283293
assertThat(context.getDefaultListableBeanFactory().getAutowireCandidateResolver())
284294
.isInstanceOf(LazyRepositoryInjectionPointResolver.class);
@@ -309,6 +319,12 @@ static class LazyConfig {}
309319
bootstrapMode = BootstrapMode.DEFERRED)
310320
static class DeferredConfig {}
311321

322+
@ComponentScan(basePackageClasses = ProductRepository.class)
323+
@EnableRepositories(basePackageClasses = ProductRepository.class,
324+
includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = AddressRepository.class),
325+
bootstrapMode = BootstrapMode.DEFERRED)
326+
static class OtherDeferredConfig {}
327+
312328
@EnableRepositories(basePackageClasses = MyOtherRepository.class,
313329
includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = MyOtherRepository.class),
314330
excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = MyOtherRepositoryImpl.class))

0 commit comments

Comments
 (0)