Skip to content

Commit 2f738be

Browse files
committed
DATACMNS-1228 - Allow custom bean name generator
1 parent 34cadd0 commit 2f738be

File tree

5 files changed

+67
-11
lines changed

5 files changed

+67
-11
lines changed

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

+17-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import javax.annotation.Nonnull;
2929

3030
import org.springframework.beans.BeanUtils;
31+
import org.springframework.beans.factory.config.BeanDefinition;
3132
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
3233
import org.springframework.context.annotation.FilterType;
3334
import org.springframework.core.annotation.AnnotationAttributes;
@@ -54,6 +55,7 @@
5455
* @author Peter Rietzler
5556
* @author Jens Schauder
5657
* @author Mark Paluch
58+
* @author Sascha Woo
5759
*/
5860
public class AnnotationRepositoryConfigurationSource extends RepositoryConfigurationSourceSupport {
5961

@@ -65,11 +67,13 @@ public class AnnotationRepositoryConfigurationSource extends RepositoryConfigura
6567
private static final String REPOSITORY_FACTORY_BEAN_CLASS = "repositoryFactoryBeanClass";
6668
private static final String REPOSITORY_BASE_CLASS = "repositoryBaseClass";
6769
private static final String CONSIDER_NESTED_REPOSITORIES = "considerNestedRepositories";
70+
private static final String BEAN_NAME_GENERATOR = "nameGenerator";
6871

6972
private final AnnotationMetadata configMetadata;
7073
private final AnnotationMetadata enableAnnotationMetadata;
7174
private final AnnotationAttributes attributes;
7275
private final ResourceLoader resourceLoader;
76+
private final RepositoryBeanNameGenerator beanNameGenerator;
7377
private final boolean hasExplicitFilters;
7478

7579
/**
@@ -85,7 +89,7 @@ public class AnnotationRepositoryConfigurationSource extends RepositoryConfigura
8589
public AnnotationRepositoryConfigurationSource(AnnotationMetadata metadata, Class<? extends Annotation> annotation,
8690
ResourceLoader resourceLoader, Environment environment, BeanDefinitionRegistry registry) {
8791

88-
super(environment, ConfigurationUtils.getRequiredClassLoader(resourceLoader), registry);
92+
super(environment, registry);
8993

9094
Assert.notNull(metadata, "Metadata must not be null!");
9195
Assert.notNull(annotation, "Annotation must not be null!");
@@ -97,10 +101,13 @@ public AnnotationRepositoryConfigurationSource(AnnotationMetadata metadata, Clas
97101
throw new IllegalStateException(String.format("Unable to obtain annotation attributes for %s!", annotation));
98102
}
99103

104+
ClassLoader classLoader = ConfigurationUtils.getRequiredClassLoader(resourceLoader);
105+
100106
this.attributes = new AnnotationAttributes(annotationAttributes);
101107
this.enableAnnotationMetadata = new StandardAnnotationMetadata(annotation);
102108
this.configMetadata = metadata;
103109
this.resourceLoader = resourceLoader;
110+
this.beanNameGenerator = getBeanNameGenerator(attributes.getClass(BEAN_NAME_GENERATOR), classLoader);
104111
this.hasExplicitFilters = hasExplicitFilters(attributes);
105112
}
106113

@@ -122,6 +129,15 @@ private static boolean hasExplicitFilters(AnnotationAttributes attributes) {
122129
return false;
123130
}
124131

132+
/*
133+
* (non-Javadoc)
134+
* @see org.springframework.data.repository.config.RepositoryConfigurationSource#generateBeanName()
135+
*/
136+
@Override
137+
public String generateBeanName(BeanDefinition beanDefinition) {
138+
return beanNameGenerator.generateBeanName(beanDefinition);
139+
}
140+
125141
/*
126142
* (non-Javadoc)
127143
* @see org.springframework.data.repository.config.RepositoryConfigurationSource#getBasePackages()

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

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

18+
import java.lang.reflect.Constructor;
19+
import java.lang.reflect.InvocationTargetException;
1820
import java.util.Collections;
1921

2022
import org.springframework.beans.factory.config.BeanDefinition;
@@ -24,6 +26,7 @@
2426
import org.springframework.core.type.filter.TypeFilter;
2527
import org.springframework.data.util.Streamable;
2628
import org.springframework.util.Assert;
29+
import org.springframework.util.ClassUtils;
2730

2831
/**
2932
* Base class to implement {@link RepositoryConfigurationSource}s.
@@ -32,31 +35,27 @@
3235
* @author Thomas Darimont
3336
* @author Peter Rietzler
3437
* @author Jens Schauder
38+
* @author Sascha Woo
3539
*/
3640
public abstract class RepositoryConfigurationSourceSupport implements RepositoryConfigurationSource {
3741

3842
protected static final String DEFAULT_REPOSITORY_IMPL_POSTFIX = "Impl";
3943

4044
private final Environment environment;
41-
private final RepositoryBeanNameGenerator beanNameGenerator;
4245
private final BeanDefinitionRegistry registry;
4346

4447
/**
4548
* Creates a new {@link RepositoryConfigurationSourceSupport} with the given environment.
4649
*
4750
* @param environment must not be {@literal null}.
48-
* @param classLoader must not be {@literal null}.
4951
* @param registry must not be {@literal null}.
5052
*/
51-
public RepositoryConfigurationSourceSupport(Environment environment, ClassLoader classLoader,
52-
BeanDefinitionRegistry registry) {
53+
public RepositoryConfigurationSourceSupport(Environment environment, BeanDefinitionRegistry registry) {
5354

5455
Assert.notNull(environment, "Environment must not be null!");
55-
Assert.notNull(classLoader, "ClassLoader must not be null!");
5656
Assert.notNull(registry, "BeanDefinitionRegistry must not be null!");
5757

5858
this.environment = environment;
59-
this.beanNameGenerator = new RepositoryBeanNameGenerator(classLoader);
6059
this.registry = registry;
6160
}
6261

@@ -94,9 +93,7 @@ public Streamable<TypeFilter> getExcludeFilters() {
9493
* @see org.springframework.data.repository.config.RepositoryConfigurationSource#getBeanNameGenerator()
9594
*/
9695
@Override
97-
public String generateBeanName(BeanDefinition beanDefinition) {
98-
return beanNameGenerator.generateBeanName(beanDefinition);
99-
}
96+
public abstract String generateBeanName(BeanDefinition beanDefinition);
10097

10198
/**
10299
* Return the {@link TypeFilter}s to define which types to include when scanning for repositories. Default
@@ -108,6 +105,15 @@ protected Iterable<TypeFilter> getIncludeFilters() {
108105
return Collections.emptySet();
109106
}
110107

108+
protected RepositoryBeanNameGenerator getBeanNameGenerator(Class<? extends RepositoryBeanNameGenerator> beanNameGenerator, ClassLoader classLoader) {
109+
try {
110+
Constructor<? extends RepositoryBeanNameGenerator> ctor = ClassUtils.getConstructorIfAvailable(beanNameGenerator, ClassLoader.class);
111+
return ctor.newInstance(classLoader);
112+
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
113+
throw new IllegalArgumentException("Unsupported bean name generator specified " + beanNameGenerator.toString());
114+
}
115+
}
116+
111117
/**
112118
* Returns whether we should consider nested repositories, i.e. repository interface definitions nested in other
113119
* classes.

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

+30-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.util.Collection;
1919
import java.util.Optional;
2020

21+
import org.springframework.beans.factory.config.BeanDefinition;
2122
import org.springframework.beans.factory.xml.ParserContext;
2223
import org.springframework.core.env.Environment;
2324
import org.springframework.core.type.filter.TypeFilter;
@@ -29,6 +30,7 @@
2930
import org.springframework.data.util.Streamable;
3031
import org.springframework.lang.Nullable;
3132
import org.springframework.util.Assert;
33+
import org.springframework.util.ClassUtils;
3234
import org.springframework.util.StringUtils;
3335
import org.w3c.dom.Element;
3436

@@ -40,6 +42,7 @@
4042
* @author Christoph Strobl
4143
* @author Peter Rietzler
4244
* @author Jens Schauder
45+
* @author Sascha Woo
4346
*/
4447
public class XmlRepositoryConfigurationSource extends RepositoryConfigurationSourceSupport {
4548

@@ -50,9 +53,11 @@ public class XmlRepositoryConfigurationSource extends RepositoryConfigurationSou
5053
private static final String REPOSITORY_FACTORY_BEAN_CLASS_NAME = "factory-class";
5154
private static final String REPOSITORY_BASE_CLASS_NAME = "base-class";
5255
private static final String CONSIDER_NESTED_REPOSITORIES = "consider-nested-repositories";
56+
private static final String BEAN_NAME_GENERATOR = "name-generator";
5357

5458
private final Element element;
5559
private final ParserContext context;
60+
private final RepositoryBeanNameGenerator beanNameGenerator;
5661

5762
private final Collection<TypeFilter> includeFilters;
5863
private final Collection<TypeFilter> excludeFilters;
@@ -66,7 +71,7 @@ public class XmlRepositoryConfigurationSource extends RepositoryConfigurationSou
6671
*/
6772
public XmlRepositoryConfigurationSource(Element element, ParserContext context, Environment environment) {
6873

69-
super(environment, ConfigurationUtils.getRequiredClassLoader(context.getReaderContext()), context.getRegistry());
74+
super(environment, context.getRegistry());
7075

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

@@ -76,6 +81,12 @@ public XmlRepositoryConfigurationSource(Element element, ParserContext context,
7681
TypeFilterParser parser = new TypeFilterParser(context.getReaderContext());
7782
this.includeFilters = parser.parseTypeFilters(element, Type.INCLUDE);
7883
this.excludeFilters = parser.parseTypeFilters(element, Type.EXCLUDE);
84+
this.beanNameGenerator = getBeanNameGenerator();
85+
}
86+
87+
@Override
88+
public String generateBeanName(BeanDefinition beanDefinition) {
89+
return beanNameGenerator.generateBeanName(beanDefinition);
7990
}
8091

8192
/*
@@ -211,4 +222,22 @@ public Optional<String> getAttribute(String name) {
211222
public boolean usesExplicitFilters() {
212223
return !(this.includeFilters.isEmpty() && this.excludeFilters.isEmpty());
213224
}
225+
226+
private RepositoryBeanNameGenerator getBeanNameGenerator() {
227+
ClassLoader classLoader = ConfigurationUtils.getRequiredClassLoader(context.getReaderContext());
228+
229+
Optional<String> attributeNameGenerator = getNullDefaultedAttribute(element, BEAN_NAME_GENERATOR);
230+
if (!attributeNameGenerator.isPresent())
231+
return new RepositoryBeanNameGenerator(classLoader);
232+
233+
try {
234+
@SuppressWarnings("unchecked")
235+
Class<? extends RepositoryBeanNameGenerator> beanNameGenerator = (Class<? extends RepositoryBeanNameGenerator>) //
236+
ClassUtils.forName(attributeNameGenerator.get(), classLoader);
237+
238+
return getBeanNameGenerator(beanNameGenerator, classLoader);
239+
} catch (ClassNotFoundException | LinkageError e) {
240+
throw new IllegalArgumentException("Unsupported bean name generator specified " + attributeNameGenerator);
241+
}
242+
}
214243
}

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

+3
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
* @author Oliver Gierke
4242
* @author Thomas Darimont
4343
* @author Mark Paluch
44+
* @author Sascha Woo
4445
*/
4546
public class AnnotationRepositoryConfigurationSourceUnitTests {
4647

@@ -165,6 +166,8 @@ static class ConfigurationWithExplicitFilter {}
165166
Filter[] includeFilters() default {};
166167

167168
Filter[] excludeFilters() default {};
169+
170+
Class<? extends RepositoryBeanNameGenerator> nameGenerator() default RepositoryBeanNameGenerator.class;
168171
}
169172

170173
@SampleAnnotation

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

+2
Original file line numberDiff line numberDiff line change
@@ -51,4 +51,6 @@
5151
boolean considerNestedRepositories() default false;
5252

5353
boolean limitImplementationBasePackages() default true;
54+
55+
Class<? extends RepositoryBeanNameGenerator> nameGenerator() default RepositoryBeanNameGenerator.class;
5456
}

0 commit comments

Comments
 (0)