Skip to content

Commit 9c3696d

Browse files
mp911dechristophstrobl
authored andcommitted
Polishing.
Improve factory methods. Integrate auditing hints in AuditingBeanRegistrationAotProcessor. Reduce visibility, improve naming. Original Pull Request: #2624
1 parent 7aafe57 commit 9c3696d

8 files changed

+81
-121
lines changed

src/main/java/org/springframework/data/aot/AuditingBeanRegistrationAotProcessor.java

+24-8
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,14 @@
1515
*/
1616
package org.springframework.data.aot;
1717

18+
import org.springframework.aop.SpringProxy;
19+
import org.springframework.aop.framework.Advised;
20+
import org.springframework.aot.hint.RuntimeHints;
21+
import org.springframework.aot.hint.TypeReference;
1822
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
1923
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
2024
import org.springframework.beans.factory.support.RegisteredBean;
21-
import org.springframework.data.aot.hint.AuditingHints;
25+
import org.springframework.core.DecoratingProxy;
2226
import org.springframework.data.domain.AuditorAware;
2327
import org.springframework.data.domain.ReactiveAuditorAware;
2428
import org.springframework.data.repository.util.ReactiveWrappers;
@@ -27,31 +31,43 @@
2731
import org.springframework.util.ClassUtils;
2832

2933
/**
34+
* {@link BeanRegistrationAotProcessor} to register runtime hints for beans that implement auditor-aware interfaces to
35+
* enable JDK proxy creation.
36+
*
3037
* @author Christoph Strobl
38+
* @author Mark Paluch
3139
* @since 3.0
3240
*/
33-
public class AuditingBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {
41+
class AuditingBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {
3442

3543
@Nullable
3644
@Override
3745
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
3846

3947
if (isAuditingHandler(registeredBean)) {
40-
return (generationContext, beanRegistrationCode) -> new AuditingHints.AuditingRuntimeHints()
41-
.registerHints(generationContext.getRuntimeHints(), registeredBean.getBeanFactory().getBeanClassLoader());
48+
return (generationContext, beanRegistrationCode) -> registerSpringProxy(AuditorAware.class,
49+
generationContext.getRuntimeHints());
4250
}
51+
4352
if (ReactiveWrappers.isAvailable(ReactiveLibrary.PROJECT_REACTOR) && isReactiveAuditorAware(registeredBean)) {
44-
return (generationContext, beanRegistrationCode) -> new AuditingHints.ReactiveAuditingRuntimeHints()
45-
.registerHints(generationContext.getRuntimeHints(), registeredBean.getBeanFactory().getBeanClassLoader());
53+
return (generationContext, beanRegistrationCode) -> registerSpringProxy(ReactiveAuditorAware.class,
54+
generationContext.getRuntimeHints());
4655
}
56+
4757
return null;
4858
}
4959

50-
boolean isAuditingHandler(RegisteredBean bean) {
60+
private static boolean isAuditingHandler(RegisteredBean bean) {
5161
return ClassUtils.isAssignable(AuditorAware.class, bean.getBeanClass());
5262
}
5363

54-
boolean isReactiveAuditorAware(RegisteredBean bean) {
64+
private static boolean isReactiveAuditorAware(RegisteredBean bean) {
5565
return ClassUtils.isAssignable(ReactiveAuditorAware.class, bean.getBeanClass());
5666
}
67+
68+
private static void registerSpringProxy(Class<?> type, RuntimeHints runtimeHints) {
69+
70+
runtimeHints.proxies().registerJdkProxy(TypeReference.of(type), TypeReference.of(SpringProxy.class),
71+
TypeReference.of(Advised.class), TypeReference.of(DecoratingProxy.class));
72+
}
5773
}

src/main/java/org/springframework/data/aot/SpringDataBeanFactoryInitializationAotProcessor.java renamed to src/main/java/org/springframework/data/aot/ManagedTypesBeanFactoryInitializationAotProcessor.java

+39-33
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package org.springframework.data.aot;
1717

1818
import java.util.Collections;
19-
import java.util.function.Function;
2019
import java.util.function.Supplier;
2120

2221
import org.apache.commons.logging.Log;
@@ -41,24 +40,12 @@
4140
*
4241
* @author Christoph Strobl
4342
* @author John Blum
44-
* @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory
45-
* @see org.springframework.beans.factory.aot.BeanFactoryInitializationAotContribution
46-
* @see org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor
4743
* @since 3.0
4844
*/
49-
public class SpringDataBeanFactoryInitializationAotProcessor implements BeanFactoryInitializationAotProcessor {
45+
public class ManagedTypesBeanFactoryInitializationAotProcessor implements BeanFactoryInitializationAotProcessor {
5046

5147
private static final Log logger = LogFactory.getLog(BeanFactoryInitializationAotProcessor.class);
5248

53-
private static final Function<Object, Object> arrayToListFunction = target ->
54-
ObjectUtils.isArray(target) ? CollectionUtils.arrayToList(target) : target;
55-
56-
private static final Function<Object, Object> asSingletonSetFunction = target ->
57-
!(target instanceof Iterable<?>) ? Collections.singleton(target) : target;
58-
59-
private static final Function<Object, Object> constructorArgumentFunction =
60-
arrayToListFunction.andThen(asSingletonSetFunction);
61-
6249
@Nullable
6350
@Override
6451
public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableListableBeanFactory beanFactory) {
@@ -70,42 +57,61 @@ public BeanFactoryInitializationAotContribution processAheadOfTime(ConfigurableL
7057
private void processManagedTypes(ConfigurableListableBeanFactory beanFactory) {
7158

7259
if (beanFactory instanceof BeanDefinitionRegistry registry) {
60+
7361
for (String beanName : beanFactory.getBeanNamesForType(ManagedTypes.class)) {
62+
postProcessManagedTypes(beanFactory, registry, beanName);
63+
}
64+
}
65+
}
7466

75-
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
67+
private void postProcessManagedTypes(ConfigurableListableBeanFactory beanFactory, BeanDefinitionRegistry registry,
68+
String beanName) {
7669

77-
if (hasConstructorArguments(beanDefinition)) {
70+
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
7871

79-
ValueHolder argumentValue = beanDefinition.getConstructorArgumentValues()
80-
.getArgumentValue(0, null, null, null);
72+
if (hasConstructorArguments(beanDefinition)) {
8173

82-
if (argumentValue.getValue() instanceof Supplier supplier) {
74+
ValueHolder argumentValue = beanDefinition.getConstructorArgumentValues().getArgumentValue(0, null, null, null);
8375

84-
if (logger.isDebugEnabled()) {
85-
logger.info(String.format("Replacing ManagedType bean definition %s.", beanName));
86-
}
76+
if (argumentValue.getValue()instanceof Supplier supplier) {
8777

88-
Object value = constructorArgumentFunction.apply(supplier.get());
78+
if (logger.isDebugEnabled()) {
79+
logger.info(String.format("Replacing ManagedType bean definition %s.", beanName));
80+
}
8981

90-
BeanDefinition beanDefinitionReplacement = newManagedTypeBeanDefinition(value);
82+
Object value = potentiallyWrapToIterable(supplier.get());
9183

92-
registry.removeBeanDefinition(beanName);
93-
registry.registerBeanDefinition(beanName, beanDefinitionReplacement);
94-
}
95-
}
84+
BeanDefinition beanDefinitionReplacement = newManagedTypeBeanDefinition(beanDefinition.getBeanClassName(),
85+
value);
86+
87+
registry.removeBeanDefinition(beanName);
88+
registry.registerBeanDefinition(beanName, beanDefinitionReplacement);
9689
}
9790
}
9891
}
9992

93+
private static Object potentiallyWrapToIterable(Object value) {
94+
95+
if (ObjectUtils.isArray(value)) {
96+
return CollectionUtils.arrayToList(value);
97+
}
98+
99+
if (value instanceof Iterable<?>) {
100+
return value;
101+
}
102+
103+
return Collections.singleton(value);
104+
}
105+
100106
private boolean hasConstructorArguments(BeanDefinition beanDefinition) {
101107
return !beanDefinition.getConstructorArgumentValues().isEmpty();
102108
}
103109

104-
private BeanDefinition newManagedTypeBeanDefinition(Object constructorArgumentValue) {
110+
private BeanDefinition newManagedTypeBeanDefinition(String managedTypesClassName, Object constructorArgumentValue) {
105111

106-
return BeanDefinitionBuilder.rootBeanDefinition(ManagedTypes.class)
107-
.setFactoryMethod("fromIterable")
108-
.addConstructorArgValue(constructorArgumentValue)
109-
.getBeanDefinition();
112+
return BeanDefinitionBuilder.rootBeanDefinition(managedTypesClassName) //
113+
.setFactoryMethod("fromIterable") //
114+
.addConstructorArgValue(constructorArgumentValue) //
115+
.getBeanDefinition();
110116
}
111117
}

src/main/java/org/springframework/data/aot/ManagedTypesBeanRegistrationAotProcessor.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
public class ManagedTypesBeanRegistrationAotProcessor implements BeanRegistrationAotProcessor {
4444

4545
private final Log logger = LogFactory.getLog(getClass());
46-
@Nullable private String moduleIdentifier;
46+
private @Nullable String moduleIdentifier;
4747

4848
@Override
4949
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {

src/main/java/org/springframework/data/aot/hint/AuditingHints.java

-74
This file was deleted.

src/main/java/org/springframework/data/aot/hint/RepositoryRuntimeHints.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
* @author Christoph Strobl
4141
* @since 3.0
4242
*/
43-
public class RepositoryRuntimeHints implements RuntimeHintsRegistrar {
43+
class RepositoryRuntimeHints implements RuntimeHintsRegistrar {
4444

4545
@Override
4646
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {

src/main/java/org/springframework/data/domain/ManagedTypes.java

+12
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package org.springframework.data.domain;
1717

1818
import java.util.ArrayList;
19+
import java.util.Arrays;
1920
import java.util.Collections;
2021
import java.util.List;
2122
import java.util.function.Consumer;
@@ -31,6 +32,7 @@
3132
*
3233
* @author Christoph Strobl
3334
* @author John Blum
35+
* @author Mark Paluch
3436
* @since 3.0
3537
*/
3638
@FunctionalInterface
@@ -47,6 +49,16 @@ static ManagedTypes empty() {
4749
return fromIterable(Collections.emptySet());
4850
}
4951

52+
/**
53+
* Factory method used to construct {@link ManagedTypes} from the given array of {@link Class types}.
54+
*
55+
* @param types array of {@link Class types} used to initialize the {@link ManagedTypes}; must not be {@literal null}.
56+
* @return new instance of {@link ManagedTypes} initialized from {@link Class types}.
57+
*/
58+
static ManagedTypes from(Class<?>... types) {
59+
return fromIterable(Arrays.asList(types));
60+
}
61+
5062
/**
5163
* Factory method used to construct {@link ManagedTypes} from the given, required {@link Iterable} of {@link Class
5264
* types}.

src/main/resources/META-INF/spring/aot.factories

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
org.springframework.beans.factory.aot.BeanFactoryInitializationAotProcessor=\
2-
org.springframework.data.aot.SpringDataBeanFactoryInitializationAotProcessor
2+
org.springframework.data.aot.ManagedTypesBeanFactoryInitializationAotProcessor
33

44
org.springframework.aot.hint.RuntimeHintsRegistrar=\
55
org.springframework.data.aot.hint.RepositoryRuntimeHints
+3-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
/**
3333
* @author Christoph Strobl
3434
*/
35-
class SpringDataBeanFactoryInitializationAotProcessorUnitTests {
35+
class ManagedTypesBeanFactoryInitializationAotProcessorUnitTests {
3636

3737
@Test // Gh-2593
3838
@SuppressWarnings("all")
@@ -47,7 +47,7 @@ void replacesManagedTypesBeanDefinitionUsingSupplierForConstructorValue() {
4747
beanFactory.registerBeanDefinition("data.managed-types", BeanDefinitionBuilder
4848
.rootBeanDefinition(ManagedTypes.class).addConstructorArgValue(typesSupplier).getBeanDefinition());
4949

50-
new SpringDataBeanFactoryInitializationAotProcessor().processAheadOfTime(beanFactory);
50+
new ManagedTypesBeanFactoryInitializationAotProcessor().processAheadOfTime(beanFactory);
5151

5252
assertThat(beanFactory.getBeanNamesForType(ManagedTypes.class)).hasSize(1);
5353
verify(typesSupplier).get();
@@ -72,7 +72,7 @@ void leavesManagedTypesBeanDefinitionNotUsingSupplierForConstructorValue() {
7272

7373
beanFactory.registerBeanDefinition("data.managed-types", sourceBeanDefinition);
7474

75-
new SpringDataBeanFactoryInitializationAotProcessor().processAheadOfTime(beanFactory);
75+
new ManagedTypesBeanFactoryInitializationAotProcessor().processAheadOfTime(beanFactory);
7676

7777
assertThat(beanFactory.getBeanNamesForType(ManagedTypes.class)).hasSize(1);
7878
verifyNoInteractions(types);

0 commit comments

Comments
 (0)