Skip to content

Commit

Permalink
DATACMNS-1497 - Configuration infrastructure now considers scanning B…
Browse files Browse the repository at this point in the history
…eanNameGenerator.

We now implement the newly introduced ImportBeanDefinitionRegistrar overload additional provided with a BeanNameGenerator configured for the import scanning. We forward this into our bean name generation infrastructure as fallback.

Related tickets: spring-projects/spring-framework#22591
  • Loading branch information
odrotbohm committed Apr 3, 2019
1 parent c4a51f1 commit 753d8bb
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
Expand All @@ -42,6 +45,7 @@
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.data.config.ConfigurationUtils;
import org.springframework.data.util.Streamable;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
Expand Down Expand Up @@ -82,11 +86,31 @@ public class AnnotationRepositoryConfigurationSource extends RepositoryConfigura
* @param resourceLoader must not be {@literal null}.
* @param environment must not be {@literal null}.
* @param registry must not be {@literal null}.
* @deprecated since 2.2. Prefer to use overload taking a {@link BeanNameGenerator} additionally.
*/
@Deprecated
public AnnotationRepositoryConfigurationSource(AnnotationMetadata metadata, Class<? extends Annotation> annotation,
ResourceLoader resourceLoader, Environment environment, BeanDefinitionRegistry registry) {
this(metadata, annotation, resourceLoader, environment, registry, null);
}

/**
* Creates a new {@link AnnotationRepositoryConfigurationSource} from the given {@link AnnotationMetadata} and
* annotation.
*
* @param metadata must not be {@literal null}.
* @param annotation must not be {@literal null}.
* @param resourceLoader must not be {@literal null}.
* @param environment must not be {@literal null}.
* @param registry must not be {@literal null}.
* @param generator can be {@literal null}.
*/
public AnnotationRepositoryConfigurationSource(AnnotationMetadata metadata, Class<? extends Annotation> annotation,
ResourceLoader resourceLoader, Environment environment, BeanDefinitionRegistry registry,
@Nullable BeanNameGenerator generator) {

super(environment, ConfigurationUtils.getRequiredClassLoader(resourceLoader), registry);
super(environment, ConfigurationUtils.getRequiredClassLoader(resourceLoader), registry,
defaultBeanNameGenerator(generator));

Assert.notNull(metadata, "Metadata must not be null!");
Assert.notNull(annotation, "Annotation must not be null!");
Expand Down Expand Up @@ -397,4 +421,20 @@ private String[] getPatterns(AnnotationAttributes filterAttributes) {
return new String[0];
}
}

/**
* Returns the {@link BeanNameGenerator} to use falling back to an {@link AnnotationBeanNameGenerator} if either the
* given generator is {@literal null} or it's the one locally declared in {@link ConfigurationClassPostProcessor}'s
* {@code importBeanNameGenerator}. This is to make sure we only use the given {@link BeanNameGenerator} if it was
* customized.
*
* @param generator can be {@literal null}.
* @return
*/
private static BeanNameGenerator defaultBeanNameGenerator(@Nullable BeanNameGenerator generator) {

return generator == null || ConfigurationClassPostProcessor.IMPORT_BEAN_NAME_GENERATOR.equals(generator) //
? new AnnotationBeanNameGenerator() //
: generator;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
Expand Down Expand Up @@ -60,9 +61,11 @@ public void setEnvironment(Environment environment) {

/*
* (non-Javadoc)
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry)
* @see org.springframework.context.annotation.ImportBeanDefinitionRegistrar#registerBeanDefinitions(org.springframework.core.type.AnnotationMetadata, org.springframework.beans.factory.support.BeanDefinitionRegistry, org.springframework.beans.factory.support.BeanNameGenerator)
*/
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry,
BeanNameGenerator generator) {

Assert.notNull(annotationMetadata, "AnnotationMetadata must not be null!");
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
Expand All @@ -74,7 +77,7 @@ public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanD
}

AnnotationRepositoryConfigurationSource configurationSource = new AnnotationRepositoryConfigurationSource(
annotationMetadata, getAnnotation(), resourceLoader, environment, registry);
annotationMetadata, getAnnotation(), resourceLoader, environment, registry, generator);

RepositoryConfigurationExtension extension = getExtension();
RepositoryConfigurationUtils.exposeRegistration(extension, registry, configurationSource);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,13 @@
*/
package org.springframework.data.repository.config;

import lombok.RequiredArgsConstructor;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues.ValueHolder;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

/**
Expand All @@ -33,12 +32,25 @@
* @author Oliver Gierke
* @author Jens Schauder
*/
@RequiredArgsConstructor
public class RepositoryBeanNameGenerator {

private static final SpringDataAnnotationBeanNameGenerator DELEGATE = new SpringDataAnnotationBeanNameGenerator();
class RepositoryBeanNameGenerator {

private final ClassLoader beanClassLoader;
private final SpringDataAnnotationBeanNameGenerator delegate;

/**
* Creates a new {@link RepositoryBeanNameGenerator} for the given {@link ClassLoader} and {@link BeanNameGenerator}.
*
* @param beanClassLoader must not be {@literal null}.
* @param generator must not be {@literal null}.
*/
public RepositoryBeanNameGenerator(ClassLoader beanClassLoader, BeanNameGenerator generator) {

Assert.notNull(beanClassLoader, "Bean ClassLoader must not be null!");
Assert.notNull(generator, "BeanNameGenerator must not be null!");

this.beanClassLoader = beanClassLoader;
this.delegate = new SpringDataAnnotationBeanNameGenerator(generator);
}

/**
* Generate a bean name for the given bean definition.
Expand All @@ -53,7 +65,7 @@ public String generateBeanName(BeanDefinition definition) {
? (AnnotatedBeanDefinition) definition //
: new AnnotatedGenericBeanDefinition(getRepositoryInterfaceFrom(definition));

return DELEGATE.generateBeanName(beanDefinition);
return delegate.generateBeanName(beanDefinition);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
Expand Down Expand Up @@ -53,14 +54,14 @@ public abstract class RepositoryConfigurationSourceSupport implements Repository
* @param registry must not be {@literal null}.
*/
public RepositoryConfigurationSourceSupport(Environment environment, ClassLoader classLoader,
BeanDefinitionRegistry registry) {
BeanDefinitionRegistry registry, BeanNameGenerator generator) {

Assert.notNull(environment, "Environment must not be null!");
Assert.notNull(classLoader, "ClassLoader must not be null!");
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");

this.environment = environment;
this.beanNameGenerator = new RepositoryBeanNameGenerator(classLoader);
this.beanNameGenerator = new RepositoryBeanNameGenerator(classLoader, generator);
this.registry = registry;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,12 @@
*/
package org.springframework.data.repository.config;

import lombok.NonNull;
import lombok.RequiredArgsConstructor;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;

/**
Expand All @@ -29,9 +33,10 @@
* @since 2.0
* @soundtrack Nils Wülker - Never Left At All (feat. Rob Summerfield)
*/
public class SpringDataAnnotationBeanNameGenerator {
@RequiredArgsConstructor
class SpringDataAnnotationBeanNameGenerator {

private final AnnotationBeanNameGenerator delegate = new AnnotationBeanNameGenerator();
private final @NonNull BeanNameGenerator delegate;

/**
* Generates a bean name for the given {@link BeanDefinition}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ public class XmlRepositoryConfigurationSource extends RepositoryConfigurationSou
*/
public XmlRepositoryConfigurationSource(Element element, ParserContext context, Environment environment) {

super(environment, ConfigurationUtils.getRequiredClassLoader(context.getReaderContext()), context.getRegistry());
super(environment, ConfigurationUtils.getRequiredClassLoader(context.getReaderContext()), context.getRegistry(),
context.getReaderContext().getReader().getBeanNameGenerator());

Assert.notNull(element, "Element must not be null!");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.env.StandardEnvironment;
Expand Down Expand Up @@ -64,7 +66,7 @@ public void registersBeanDefinitionForFoundBean() {

AnnotationMetadata metadata = new StandardAnnotationMetadata(SampleConfiguration.class, true);

registrar.registerBeanDefinitions(metadata, registry);
registrar.registerBeanDefinitions(metadata, registry, null);

assertBeanDefinitionRegisteredFor("myRepository");
assertBeanDefinitionRegisteredFor("composedRepository");
Expand All @@ -78,7 +80,7 @@ public void registersBeanDefinitionWithoutFragmentImplementations() {

AnnotationMetadata metadata = new StandardAnnotationMetadata(FragmentExclusionConfiguration.class, true);

registrar.registerBeanDefinitions(metadata, registry);
registrar.registerBeanDefinitions(metadata, registry, null);

assertBeanDefinitionRegisteredFor("repositoryWithFragmentExclusion");
assertNoBeanDefinitionRegisteredFor("excludedRepositoryImpl");
Expand All @@ -89,7 +91,7 @@ public void shouldLimitImplementationBasePackages() {

AnnotationMetadata metadata = new StandardAnnotationMetadata(LimitsImplementationBasePackages.class, true);

registrar.registerBeanDefinitions(metadata, registry);
registrar.registerBeanDefinitions(metadata, registry, null);

assertBeanDefinitionRegisteredFor("personRepository");
assertNoBeanDefinitionRegisteredFor("fragmentImpl");
Expand All @@ -98,17 +100,30 @@ public void shouldLimitImplementationBasePackages() {
@Test // DATACMNS-360
public void registeredProfileRepositoriesIfProfileActivated() {

StandardAnnotationMetadata metadata = new StandardAnnotationMetadata(SampleConfiguration.class, true);
AnnotationMetadata metadata = new StandardAnnotationMetadata(SampleConfiguration.class, true);
environment.setActiveProfiles("profile");

DummyRegistrar registrar = new DummyRegistrar();
registrar.setEnvironment(environment);

registrar.registerBeanDefinitions(metadata, registry);
registrar.registerBeanDefinitions(metadata, registry, null);

assertBeanDefinitionRegisteredFor("myRepository", "profileRepository");
}

@Test // DATACMNS-1497
public void usesBeanNameGeneratorProvided() {

AnnotationMetadata metadata = new StandardAnnotationMetadata(SampleConfiguration.class, true);
BeanNameGenerator delegate = new AnnotationBeanNameGenerator();

DummyRegistrar registrar = new DummyRegistrar();
registrar.setEnvironment(environment);
registrar.registerBeanDefinitions(metadata, registry,
(definition, registry) -> delegate.generateBeanName(definition, registry).concat("Hello"));

assertBeanDefinitionRegisteredFor("myRepositoryHello");
}

private void assertBeanDefinitionRegisteredFor(String... names) {

for (String name : names) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.ScannedGenericBeanDefinition;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
Expand All @@ -48,7 +49,8 @@ public class RepositoryBeanNameGeneratorUnitTests {

@Before
public void setUp() {
this.generator = new RepositoryBeanNameGenerator(Thread.currentThread().getContextClassLoader());
this.generator = new RepositoryBeanNameGenerator(Thread.currentThread().getContextClassLoader(),
new AnnotationBeanNameGenerator());
}

@Test
Expand Down

0 comments on commit 753d8bb

Please sign in to comment.