Skip to content

Commit d334c5a

Browse files
mp911dechristophstrobl
authored andcommitted
Polishing.
Adopt to Framework changes. Simplify auditing bean registration. Remove ImportRuntimeHints in EnableMongoAuditing. Refine ManagedTypes bean definitions. Consistently use mongo as bean name prefix. Depend on store-specific ManagedTypes. Rewrite ReactiveMongoAuditingRegistrar to avoid inner beans. Reduce AOT processor visibility. Cleanup imports. Improve type naming. Update Javadoc. Original Pull Request: #4093
1 parent cfd55be commit d334c5a

16 files changed

+128
-70
lines changed

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/MongoManagedTypes.java

+34-3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.springframework.data.mongodb;
1717

18+
import java.util.Arrays;
1819
import java.util.function.Consumer;
1920

2021
import org.springframework.data.domain.ManagedTypes;
@@ -27,19 +28,49 @@ public final class MongoManagedTypes implements ManagedTypes {
2728

2829
private final ManagedTypes delegate;
2930

30-
public MongoManagedTypes(ManagedTypes types) {
31+
private MongoManagedTypes(ManagedTypes types) {
3132
this.delegate = types;
3233
}
3334

35+
/**
36+
* Wraps an existing {@link ManagedTypes} object with {@link MongoManagedTypes}.
37+
*
38+
* @param managedTypes
39+
* @return
40+
*/
3441
public static MongoManagedTypes from(ManagedTypes managedTypes) {
3542
return new MongoManagedTypes(managedTypes);
3643
}
3744

38-
public static MongoManagedTypes of(Iterable<? extends Class<?>> types) {
45+
/**
46+
* Factory method used to construct {@link MongoManagedTypes} from the given array of {@link Class types}.
47+
*
48+
* @param types array of {@link Class types} used to initialize the {@link ManagedTypes}; must not be {@literal null}.
49+
* @return new instance of {@link MongoManagedTypes} initialized from {@link Class types}.
50+
*/
51+
public static MongoManagedTypes from(Class<?>... types) {
52+
return fromIterable(Arrays.asList(types));
53+
}
54+
55+
/**
56+
* Factory method used to construct {@link MongoManagedTypes} from the given, required {@link Iterable} of
57+
* {@link Class types}.
58+
*
59+
* @param types {@link Iterable} of {@link Class types} used to initialize the {@link ManagedTypes}; must not be
60+
* {@literal null}.
61+
* @return new instance of {@link MongoManagedTypes} initialized the given, required {@link Iterable} of {@link Class
62+
* types}.
63+
*/
64+
public static MongoManagedTypes fromIterable(Iterable<? extends Class<?>> types) {
3965
return from(ManagedTypes.fromIterable(types));
4066
}
4167

42-
public static MongoManagedTypes none() {
68+
/**
69+
* Factory method to return an empty {@link MongoManagedTypes} object.
70+
*
71+
* @return an empty {@link MongoManagedTypes} object.
72+
*/
73+
public static MongoManagedTypes empty() {
4374
return from(ManagedTypes.empty());
4475
}
4576

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/AotMongoRepositoryPostProcessor.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
*/
2828
public class AotMongoRepositoryPostProcessor extends RepositoryRegistrationAotProcessor {
2929

30-
private LazyLoadingProxyAotProcessor lazyLoadingProxyAotProcessor = new LazyLoadingProxyAotProcessor();
30+
private final LazyLoadingProxyAotProcessor lazyLoadingProxyAotProcessor = new LazyLoadingProxyAotProcessor();
3131

3232
@Override
3333
protected void contribute(AotRepositoryContext repositoryContext, GenerationContext generationContext) {

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/LazyLoadingProxyAotProcessor.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
* @author Christoph Strobl
3737
* @since 4.0
3838
*/
39-
public class LazyLoadingProxyAotProcessor {
39+
class LazyLoadingProxyAotProcessor {
4040

4141
private boolean generalLazyLoadingProxyContributed = false;
4242

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/aot/MongoManagedTypesBeanRegistrationAotProcessor.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@
2626
* @author Christoph Strobl
2727
* @since 2022/06
2828
*/
29-
public class MongoManagedTypesBeanRegistrationAotProcessor extends ManagedTypesBeanRegistrationAotProcessor {
29+
class MongoManagedTypesBeanRegistrationAotProcessor extends ManagedTypesBeanRegistrationAotProcessor {
3030

31-
private LazyLoadingProxyAotProcessor lazyLoadingProxyAotProcessor = new LazyLoadingProxyAotProcessor();
31+
private final LazyLoadingProxyAotProcessor lazyLoadingProxyAotProcessor = new LazyLoadingProxyAotProcessor();
3232

3333
public MongoManagedTypesBeanRegistrationAotProcessor() {
3434
setModuleIdentifier("mongo");
+23-1
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,26 @@
2525
import org.springframework.data.mongodb.core.mapping.event.AfterSaveCallback;
2626
import org.springframework.data.mongodb.core.mapping.event.BeforeConvertCallback;
2727
import org.springframework.data.mongodb.core.mapping.event.BeforeSaveCallback;
28+
import org.springframework.data.mongodb.core.mapping.event.ReactiveAfterConvertCallback;
29+
import org.springframework.data.mongodb.core.mapping.event.ReactiveAfterSaveCallback;
30+
import org.springframework.data.mongodb.core.mapping.event.ReactiveBeforeConvertCallback;
31+
import org.springframework.data.mongodb.core.mapping.event.ReactiveBeforeSaveCallback;
2832
import org.springframework.data.mongodb.repository.support.SimpleMongoRepository;
33+
import org.springframework.data.mongodb.repository.support.SimpleReactiveMongoRepository;
34+
import org.springframework.data.repository.util.ReactiveWrappers;
2935
import org.springframework.lang.Nullable;
3036

3137
/**
38+
* {@link RuntimeHintsRegistrar} for repository types and entity callbacks.
39+
*
3240
* @author Christoph Strobl
41+
* @author Mark Paluch
3342
* @since 4.0
3443
*/
35-
public class DataMongoRuntimeHints implements RuntimeHintsRegistrar {
44+
class MongoRuntimeHints implements RuntimeHintsRegistrar {
45+
46+
private static final boolean PROJECT_REACTOR_PRESENT = ReactiveWrappers
47+
.isAvailable(ReactiveWrappers.ReactiveLibrary.PROJECT_REACTOR);
3648

3749
@Override
3850
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
@@ -43,5 +55,15 @@ public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader)
4355
TypeReference.of(AfterSaveCallback.class)),
4456
builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
4557
MemberCategory.INVOKE_PUBLIC_METHODS));
58+
59+
if (PROJECT_REACTOR_PRESENT) {
60+
61+
hints.reflection()
62+
.registerTypes(Arrays.asList(TypeReference.of(SimpleReactiveMongoRepository.class),
63+
TypeReference.of(ReactiveBeforeConvertCallback.class), TypeReference.of(ReactiveBeforeSaveCallback.class),
64+
TypeReference.of(ReactiveAfterConvertCallback.class), TypeReference.of(ReactiveAfterSaveCallback.class)),
65+
builder -> builder.withMembers(MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
66+
MemberCategory.INVOKE_PUBLIC_METHODS));
67+
}
4668
}
4769
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/AbstractMongoClientConfiguration.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ public MongoDatabaseFactory mongoDbFactory() {
8080

8181
/**
8282
* Creates a {@link MappingMongoConverter} using the configured {@link #mongoDbFactory()} and
83-
* {@link #mongoMappingContext(MongoCustomConversions)}. Will get {@link #customConversions()} applied.
83+
* {@link #mongoMappingContext(MongoCustomConversions, org.springframework.data.mongodb.MongoManagedTypes)}. Will get {@link #customConversions()} applied.
8484
*
8585
* @see #customConversions()
86-
* @see #mongoMappingContext(MongoCustomConversions)
86+
* @see #mongoMappingContext(MongoCustomConversions, org.springframework.data.mongodb.MongoManagedTypes)
8787
* @see #mongoDbFactory()
8888
*/
8989
@Bean

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/AbstractReactiveMongoConfiguration.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ public ReactiveMongoDatabaseFactory reactiveMongoDbFactory() {
8484

8585
/**
8686
* Creates a {@link MappingMongoConverter} using the configured {@link #reactiveMongoDbFactory()} and
87-
* {@link #mongoMappingContext(MongoCustomConversions)}. Will get {@link #customConversions()} applied.
87+
* {@link #mongoMappingContext(MongoCustomConversions, org.springframework.data.mongodb.MongoManagedTypes)}. Will get {@link #customConversions()} applied.
8888
*
8989
* @see #customConversions()
90-
* @see #mongoMappingContext(MongoCustomConversions)
90+
* @see #mongoMappingContext(MongoCustomConversions, org.springframework.data.mongodb.MongoManagedTypes)
9191
* @see #reactiveMongoDbFactory()
9292
* @return never {@literal null}.
9393
*/

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/EnableMongoAuditing.java

-3
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,6 @@
2323
import java.lang.annotation.Target;
2424

2525
import org.springframework.context.annotation.Import;
26-
import org.springframework.context.annotation.ImportRuntimeHints;
27-
import org.springframework.data.aot.hint.AuditingHints;
2826
import org.springframework.data.auditing.DateTimeProvider;
2927
import org.springframework.data.domain.AuditorAware;
3028

@@ -39,7 +37,6 @@
3937
@Target(ElementType.TYPE)
4038
@Retention(RetentionPolicy.RUNTIME)
4139
@Import(MongoAuditingRegistrar.class)
42-
@ImportRuntimeHints(AuditingHints.AuditingRuntimeHints.class)
4340
public @interface EnableMongoAuditing {
4441

4542
/**

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoAuditingRegistrar.java

+41-34
Original file line numberDiff line numberDiff line change
@@ -17,20 +17,20 @@
1717

1818
import java.lang.annotation.Annotation;
1919

20+
import org.springframework.beans.factory.ListableBeanFactory;
2021
import org.springframework.beans.factory.config.BeanDefinition;
2122
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2223
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
2324
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
24-
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
2525
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
2626
import org.springframework.core.Ordered;
27-
import org.springframework.core.type.AnnotationMetadata;
2827
import org.springframework.data.auditing.IsNewAwareAuditingHandler;
2928
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
3029
import org.springframework.data.auditing.config.AuditingConfiguration;
3130
import org.springframework.data.config.ParsingUtils;
3231
import org.springframework.data.mapping.context.PersistentEntities;
3332
import org.springframework.data.mongodb.core.mapping.event.AuditingEntityCallback;
33+
import org.springframework.lang.Nullable;
3434
import org.springframework.util.Assert;
3535

3636
/**
@@ -52,45 +52,19 @@ protected String getAuditingHandlerBeanName() {
5252
return "mongoAuditingHandler";
5353
}
5454

55-
String persistentEntitiesBeanName;
56-
5755
@Override
58-
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
59-
60-
Assert.notNull(annotationMetadata, "AnnotationMetadata must not be null");
61-
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
62-
63-
if(persistentEntitiesBeanName == null) {
64-
if (registry instanceof DefaultListableBeanFactory beanFactory) {
65-
for (String bn : beanFactory.getBeanNamesForType(PersistentEntities.class)) {
66-
if (bn.startsWith("mongo")) {
67-
persistentEntitiesBeanName = bn;
68-
}
69-
}
70-
}
71-
if(persistentEntitiesBeanName == null) {
72-
73-
persistentEntitiesBeanName = BeanDefinitionReaderUtils.uniqueBeanName("mongo.persistent-entities", registry);
74-
75-
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntities.class)
76-
.setFactoryMethod("of")
77-
//.addConstructorArgValue(new RuntimeBeanReference(MongoMappingContext.class))
78-
.addConstructorArgReference("mongoMappingContext");
79-
registry.registerBeanDefinition(persistentEntitiesBeanName, definition.getBeanDefinition());
80-
}
81-
}
82-
83-
super.registerBeanDefinitions(annotationMetadata, registry);
56+
protected void postProcess(BeanDefinitionBuilder builder, AuditingConfiguration configuration,
57+
BeanDefinitionRegistry registry) {
58+
potentiallyRegisterMongoPersistentEntities(builder, registry);
8459
}
8560

8661
@Override
8762
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
8863

8964
Assert.notNull(configuration, "AuditingConfiguration must not be null");
9065

91-
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class);
92-
builder.addConstructorArgReference(persistentEntitiesBeanName);
93-
return configureDefaultAuditHandlerAttributes(configuration, builder);
66+
return configureDefaultAuditHandlerAttributes(configuration,
67+
BeanDefinitionBuilder.rootBeanDefinition(IsNewAwareAuditingHandler.class));
9468
}
9569

9670
@Override
@@ -109,9 +83,42 @@ protected void registerAuditListenerBeanDefinition(BeanDefinition auditingHandle
10983
AuditingEntityCallback.class.getName(), registry);
11084
}
11185

112-
11386
@Override
11487
public int getOrder() {
11588
return Ordered.LOWEST_PRECEDENCE;
11689
}
90+
91+
static void potentiallyRegisterMongoPersistentEntities(BeanDefinitionBuilder builder,
92+
BeanDefinitionRegistry registry) {
93+
94+
String persistentEntitiesBeanName = MongoAuditingRegistrar.detectPersistentEntitiesBeanName(registry);
95+
96+
if (persistentEntitiesBeanName == null) {
97+
98+
persistentEntitiesBeanName = BeanDefinitionReaderUtils.uniqueBeanName("mongoPersistentEntities", registry);
99+
100+
// TODO: https://github.com/spring-projects/spring-framework/issues/28728
101+
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntities.class) //
102+
.setFactoryMethod("of") //
103+
.addConstructorArgReference("mongoMappingContext");
104+
105+
registry.registerBeanDefinition(persistentEntitiesBeanName, definition.getBeanDefinition());
106+
}
107+
108+
builder.addConstructorArgReference(persistentEntitiesBeanName);
109+
}
110+
111+
@Nullable
112+
private static String detectPersistentEntitiesBeanName(BeanDefinitionRegistry registry) {
113+
114+
if (registry instanceof ListableBeanFactory beanFactory) {
115+
for (String bn : beanFactory.getBeanNamesForType(PersistentEntities.class)) {
116+
if (bn.startsWith("mongo")) {
117+
return bn;
118+
}
119+
}
120+
}
121+
122+
return null;
123+
}
117124
}

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/MongoConfigurationSupport.java

+5-6
Original file line numberDiff line numberDiff line change
@@ -78,14 +78,13 @@ protected Collection<String> getMappingBasePackages() {
7878
*
7979
* @see #getMappingBasePackages()
8080
* @return
81-
* @throws ClassNotFoundException
8281
*/
8382
@Bean
84-
public MongoMappingContext mongoMappingContext(MongoCustomConversions customConversions, ManagedTypes managedTypes)
85-
throws ClassNotFoundException {
83+
public MongoMappingContext mongoMappingContext(MongoCustomConversions customConversions,
84+
MongoManagedTypes mongoManagedTypes) {
8685

8786
MongoMappingContext mappingContext = new MongoMappingContext();
88-
mappingContext.setManagedTypes(managedTypes);
87+
mappingContext.setManagedTypes(mongoManagedTypes);
8988
mappingContext.setSimpleTypeHolder(customConversions.getSimpleTypeHolder());
9089
mappingContext.setFieldNamingStrategy(fieldNamingStrategy());
9190
mappingContext.setAutoIndexCreation(autoIndexCreation());
@@ -99,8 +98,8 @@ public MongoMappingContext mongoMappingContext(MongoCustomConversions customConv
9998
* @since 4.0
10099
*/
101100
@Bean
102-
public MongoManagedTypes managedTypes() throws ClassNotFoundException {
103-
return MongoManagedTypes.of(getInitialEntitySet());
101+
public MongoManagedTypes mongoManagedTypes() throws ClassNotFoundException {
102+
return MongoManagedTypes.fromIterable(getInitialEntitySet());
104103
}
105104

106105
/**

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/config/ReactiveMongoAuditingRegistrar.java

+8-9
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,9 @@
1818
import java.lang.annotation.Annotation;
1919

2020
import org.springframework.beans.factory.config.BeanDefinition;
21-
import org.springframework.beans.factory.support.AbstractBeanDefinition;
2221
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
2322
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
2423
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
25-
import org.springframework.core.type.AnnotationMetadata;
2624
import org.springframework.data.auditing.ReactiveIsNewAwareAuditingHandler;
2725
import org.springframework.data.auditing.config.AuditingBeanDefinitionRegistrarSupport;
2826
import org.springframework.data.auditing.config.AuditingConfiguration;
@@ -48,18 +46,19 @@ protected String getAuditingHandlerBeanName() {
4846
return "reactiveMongoAuditingHandler";
4947
}
5048

49+
@Override
50+
protected void postProcess(BeanDefinitionBuilder builder, AuditingConfiguration configuration,
51+
BeanDefinitionRegistry registry) {
52+
MongoAuditingRegistrar.potentiallyRegisterMongoPersistentEntities(builder, registry);
53+
}
54+
5155
@Override
5256
protected BeanDefinitionBuilder getAuditHandlerBeanDefinitionBuilder(AuditingConfiguration configuration) {
5357

5458
Assert.notNull(configuration, "AuditingConfiguration must not be null");
5559

56-
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(ReactiveIsNewAwareAuditingHandler.class);
57-
58-
BeanDefinitionBuilder definition = BeanDefinitionBuilder.genericBeanDefinition(PersistentEntitiesFactoryBean.class);
59-
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
60-
61-
builder.addConstructorArgValue(definition.getBeanDefinition());
62-
return configureDefaultAuditHandlerAttributes(configuration, builder);
60+
return configureDefaultAuditHandlerAttributes(configuration,
61+
BeanDefinitionBuilder.rootBeanDefinition(ReactiveIsNewAwareAuditingHandler.class));
6362
}
6463

6564
@Override

spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/config/MongoRepositoryConfigurationExtension.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
import org.springframework.data.repository.config.RepositoryConfigurationExtensionSupport;
3232
import org.springframework.data.repository.config.XmlRepositoryConfigurationSource;
3333
import org.springframework.data.repository.core.RepositoryMetadata;
34-
import org.springframework.lang.NonNull;
34+
3535
import org.w3c.dom.Element;
3636

3737
/**
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
org.springframework.aot.hint.RuntimeHintsRegistrar=\
2-
org.springframework.data.mongodb.aot.DataMongoRuntimeHints
2+
org.springframework.data.mongodb.aot.MongoRuntimeHints
3+
34
org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\
45
org.springframework.data.mongodb.aot.MongoManagedTypesBeanRegistrationAotProcessor

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/aot/RepositoryRegistrationAotContributionAssert.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public RepositoryRegistrationAotContributionAssert codeContributionSatisfies(
8787
BeanRegistrationCode mockBeanRegistrationCode = mock(BeanRegistrationCode.class);
8888

8989
DefaultGenerationContext generationContext =
90-
new DefaultGenerationContext(new ClassNameGenerator(), new InMemoryGeneratedFiles(), new RuntimeHints());
90+
new DefaultGenerationContext(new ClassNameGenerator(Object.class), new InMemoryGeneratedFiles());
9191

9292
this.actual.applyTo(generationContext, mockBeanRegistrationCode);
9393

spring-data-mongodb/src/test/java/org/springframework/data/mongodb/config/AbstractMongoConfigurationUnitTests.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ public void containsMongoDbFactoryButNoMongoBean() {
9393
public void returnsUninitializedMappingContext() throws Exception {
9494

9595
SampleMongoConfiguration configuration = new SampleMongoConfiguration();
96-
MongoMappingContext context = configuration.mongoMappingContext(configuration.customConversions(), MongoManagedTypes.of(Collections.singleton(Entity.class)));
96+
MongoMappingContext context = configuration.mongoMappingContext(configuration.customConversions(),
97+
MongoManagedTypes.from(Entity.class));
9798

9899
assertThat(context.getPersistentEntities()).isEmpty();
99100
context.initialize();

0 commit comments

Comments
 (0)