Skip to content

Commit 48dbc25

Browse files
xeounxzxump911de
authored andcommitted
Avoid multiple DeferredRepositoryInitializationListener registrations in RepositoryConfigurationDelegate.
Closes #3287 Original pull request: #3219
1 parent 60a8f0c commit 48dbc25

File tree

2 files changed

+39
-31
lines changed

2 files changed

+39
-31
lines changed

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

Lines changed: 14 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,27 +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;
2920
import org.springframework.beans.factory.config.BeanDefinition;
3021
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
3122
import org.springframework.beans.factory.config.DependencyDescriptor;
3223
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
33-
import org.springframework.beans.factory.support.AutowireCandidateResolver;
34-
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
35-
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
36-
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
37-
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
38-
import org.springframework.beans.factory.support.RootBeanDefinition;
24+
import org.springframework.beans.factory.support.*;
3925
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
4026
import org.springframework.context.support.GenericApplicationContext;
4127
import org.springframework.core.ResolvableType;
@@ -57,6 +43,10 @@
5743
import org.springframework.util.ClassUtils;
5844
import org.springframework.util.StopWatch;
5945

46+
import java.lang.reflect.TypeVariable;
47+
import java.util.*;
48+
import java.util.stream.Collectors;
49+
6050
/**
6151
* Delegate for configuration integration to reuse the general way of detecting repositories. Customization is done by
6252
* providing a configuration format specific {@link RepositoryConfigurationSource} (currently either XML or annotations
@@ -92,7 +82,7 @@ public class RepositoryConfigurationDelegate {
9282
* @param environment must not be {@literal null}.
9383
*/
9484
public RepositoryConfigurationDelegate(RepositoryConfigurationSource configurationSource,
95-
ResourceLoader resourceLoader, Environment environment) {
85+
ResourceLoader resourceLoader, Environment environment) {
9686

9787
this.isXml = configurationSource instanceof XmlRepositoryConfigurationSource;
9888
boolean isAnnotation = configurationSource instanceof AnnotationRepositoryConfigurationSource;
@@ -117,7 +107,7 @@ public RepositoryConfigurationDelegate(RepositoryConfigurationSource configurati
117107
* {@link Environment}.
118108
*/
119109
private static Environment defaultEnvironment(@Nullable Environment environment,
120-
@Nullable ResourceLoader resourceLoader) {
110+
@Nullable ResourceLoader resourceLoader) {
121111

122112
if (environment != null) {
123113
return environment;
@@ -137,7 +127,7 @@ private static Environment defaultEnvironment(@Nullable Environment environment,
137127
* @see org.springframework.beans.factory.support.BeanDefinitionRegistry
138128
*/
139129
public List<BeanComponentDefinition> registerRepositoriesIn(BeanDefinitionRegistry registry,
140-
RepositoryConfigurationExtension extension) {
130+
RepositoryConfigurationExtension extension) {
141131

142132
if (logger.isInfoEnabled()) {
143133
logger.info(LogMessage.format("Bootstrapping Spring Data %s repositories in %s mode.", //
@@ -223,7 +213,7 @@ public List<BeanComponentDefinition> registerRepositoriesIn(BeanDefinitionRegist
223213
}
224214

225215
private void registerAotComponents(BeanDefinitionRegistry registry, RepositoryConfigurationExtension extension,
226-
Map<String, RepositoryConfigurationAdapter<?>> metadataByRepositoryBeanName) {
216+
Map<String, RepositoryConfigurationAdapter<?>> metadataByRepositoryBeanName) {
227217

228218
BeanDefinitionBuilder repositoryAotProcessor = BeanDefinitionBuilder
229219
.rootBeanDefinition(extension.getRepositoryAotProcessor()).setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
@@ -246,7 +236,7 @@ private void registerAotComponents(BeanDefinitionRegistry registry, RepositoryCo
246236
* @param registry must not be {@literal null}.
247237
*/
248238
private static void potentiallyLazifyRepositories(Map<String, RepositoryConfiguration<?>> configurations,
249-
BeanDefinitionRegistry registry, BootstrapMode mode) {
239+
BeanDefinitionRegistry registry, BootstrapMode mode) {
250240

251241
if (!DefaultListableBeanFactory.class.isInstance(registry) || BootstrapMode.DEFAULT.equals(mode)) {
252242
return;
@@ -273,8 +263,10 @@ private static void potentiallyLazifyRepositories(Map<String, RepositoryConfigur
273263

274264
logger.debug("Registering deferred repository initialization listener.");
275265

276-
beanFactory.registerSingleton(DeferredRepositoryInitializationListener.class.getName(),
277-
new DeferredRepositoryInitializationListener(beanFactory));
266+
if (!beanFactory.containsBean(DeferredRepositoryInitializationListener.class.getName())) {
267+
beanFactory.registerSingleton(DeferredRepositoryInitializationListener.class.getName(),
268+
new DeferredRepositoryInitializationListener(beanFactory));
269+
}
278270
}
279271
}
280272

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

Lines changed: 25 additions & 9 deletions
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;
@@ -60,11 +53,19 @@
6053
import org.springframework.data.repository.sample.AddressRepositoryClient;
6154
import org.springframework.data.repository.sample.ProductRepository;
6255

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

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

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

116126
@Test // DATACMNS-1832
@@ -277,9 +287,9 @@ void considersGenericLength() {
277287
assertThat(it.getGeneric(1).resolve()).isEqualTo(Person.class);
278288
}
279289

280-
private static ListableBeanFactory assertLazyRepositoryBeanSetup(Class<?> configClass) {
290+
private static ListableBeanFactory assertLazyRepositoryBeanSetup(Class<?>... componentClasses) {
281291

282-
var context = new AnnotationConfigApplicationContext(configClass);
292+
var context = new AnnotationConfigApplicationContext(componentClasses);
283293

284294
assertThat(context.getDefaultListableBeanFactory().getAutowireCandidateResolver())
285295
.isInstanceOf(LazyRepositoryInjectionPointResolver.class);
@@ -310,6 +320,12 @@ static class LazyConfig {}
310320
bootstrapMode = BootstrapMode.DEFERRED)
311321
static class DeferredConfig {}
312322

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

0 commit comments

Comments
 (0)