DATACMNS-609 - Improved bean definition registration for repository configuration.
The bean definitions that were registered for a repository configuration setup we registered once for every usage of the repository configuration element (annotation or XML). This caused multiple registrations of the very same bean definition which - as in case of the RepositoryInterfaceAwareBeanPostProcessor - apparently leads to performance problems in the container startup. Feedback for the latter claim is already asked for but we improved the registration setup nonetheless. Introduced a registerIfNotAlreadyRegistered(…) method on RepositoryConfigurationExtensionSupport to allow easy registration of to-b-registered-once-and-only-once beans. We now hint towards the newly introduced method in registerWithSourceAndGeneratedBeanName(…).
This commit is contained in:
@@ -118,7 +118,7 @@ public abstract class RepositoryConfigurationExtensionSupport implements Reposit
|
||||
AbstractBeanDefinition definition = BeanDefinitionBuilder.rootBeanDefinition(REPOSITORY_INTERFACE_POST_PROCESSOR)
|
||||
.getBeanDefinition();
|
||||
|
||||
registerWithSourceAndGeneratedBeanName(registry, definition, configurationSource.getSource());
|
||||
registerIfNotAlreadyRegistered(definition, registry, REPOSITORY_INTERFACE_POST_PROCESSOR, configurationSource);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -169,12 +169,15 @@ public abstract class RepositoryConfigurationExtensionSupport implements Reposit
|
||||
|
||||
/**
|
||||
* Sets the given source on the given {@link AbstractBeanDefinition} and registers it inside the given
|
||||
* {@link BeanDefinitionRegistry}.
|
||||
* {@link BeanDefinitionRegistry}. For {@link BeanDefinition}s to be registerd once-and-only-once for all
|
||||
* configuration elements (annotation or XML), prefer calling
|
||||
* {@link #registerIfNotAlreadyRegistered(AbstractBeanDefinition, BeanDefinitionRegistry, String, Object)} with a
|
||||
* dedicated bean name to avoid the bead definition being registered multiple times. *
|
||||
*
|
||||
* @param registry
|
||||
* @param bean
|
||||
* @param source
|
||||
* @return
|
||||
* @param registry must not be {@literal null}.
|
||||
* @param bean must not be {@literal null}.
|
||||
* @param source must not be {@literal null}.
|
||||
* @return the bean name generated for the given {@link BeanDefinition}
|
||||
*/
|
||||
public static String registerWithSourceAndGeneratedBeanName(BeanDefinitionRegistry registry,
|
||||
AbstractBeanDefinition bean, Object source) {
|
||||
@@ -187,6 +190,26 @@ public abstract class RepositoryConfigurationExtensionSupport implements Reposit
|
||||
return beanName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the given {@link AbstractBeanDefinition} with the given registry with the given bean name unless the
|
||||
* registry already contains a bean with that name.
|
||||
*
|
||||
* @param bean must not be {@literal null}.
|
||||
* @param registry must not be {@literal null}.
|
||||
* @param beanName must not be {@literal null} or empty.
|
||||
* @param source must not be {@literal null}.
|
||||
*/
|
||||
public static void registerIfNotAlreadyRegistered(AbstractBeanDefinition bean, BeanDefinitionRegistry registry,
|
||||
String beanName, Object source) {
|
||||
|
||||
if (registry.containsBeanDefinition(beanName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
bean.setSource(source);
|
||||
registry.registerBeanDefinition(beanName, bean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given {@link BeanDefinitionRegistry} already contains a bean of the given type assuming the
|
||||
* bean name has been autogenerated.
|
||||
|
||||
@@ -23,7 +23,12 @@ import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.StandardAnnotationMetadata;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
|
||||
|
||||
@@ -60,6 +65,26 @@ public class RepositoryConfigurationExtensionSupportUnitTests {
|
||||
assertThat(extension.isStrictRepositoryCandidate(ExtendingInterface.class), is(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-609
|
||||
*/
|
||||
@Test
|
||||
public void registersRepositoryInterfaceAwareBeanPostProcessorOnlyOnceForMultipleConfigurations() {
|
||||
|
||||
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
|
||||
AnnotationMetadata annotationMetadata = new StandardAnnotationMetadata(SampleConfiguration.class, true);
|
||||
|
||||
DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
|
||||
StandardEnvironment environment = new StandardEnvironment();
|
||||
AnnotationRepositoryConfigurationSource configurationSource = new AnnotationRepositoryConfigurationSource(
|
||||
annotationMetadata, EnableRepositories.class, resourceLoader, environment);
|
||||
|
||||
extension.registerBeansForRoot(beanFactory, configurationSource);
|
||||
extension.registerBeansForRoot(beanFactory, configurationSource);
|
||||
|
||||
assertThat(beanFactory.getBeanDefinitionCount(), is(1));
|
||||
}
|
||||
|
||||
static class SampleRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport {
|
||||
|
||||
@Override
|
||||
@@ -95,4 +120,7 @@ public class RepositoryConfigurationExtensionSupportUnitTests {
|
||||
interface StoreInterface {}
|
||||
|
||||
interface ExtendingInterface extends StoreInterface, Repository<PlainType, Long> {}
|
||||
|
||||
@EnableRepositories
|
||||
static class SampleConfiguration {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user