Skip to content

Commit 8d79ec0

Browse files
committed
Allow AOT contributions to customize code fragments.
Update the `BeanRegistrationAotContribution` interface to allow it to customize `BeanRegistrationCodeFragments`. This change allows us to drop the `BeanRegistrationCodeFragmentsCustomizer` interface since an `BeanRegistrationAotProcessor` can now be used instead. Closes gh-28557
1 parent 74caa92 commit 8d79ec0

File tree

11 files changed

+143
-156
lines changed

11 files changed

+143
-156
lines changed
Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@
2626

2727
import org.springframework.aot.generate.GeneratedMethod;
2828
import org.springframework.aot.generate.GenerationContext;
29+
import org.springframework.beans.factory.aot.BeanRegistrationAotContribution;
30+
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor;
2931
import org.springframework.beans.factory.aot.BeanRegistrationCode;
3032
import org.springframework.beans.factory.aot.BeanRegistrationCodeFragments;
31-
import org.springframework.beans.factory.aot.BeanRegistrationCodeFragmentsCustomizer;
3233
import org.springframework.beans.factory.config.BeanDefinition;
3334
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
3435
import org.springframework.beans.factory.support.InstanceSupplier;
@@ -39,39 +40,37 @@
3940
import org.springframework.lang.Nullable;
4041

4142
/**
42-
* {@link BeanRegistrationCodeFragmentsCustomizer} for
43-
* {@link ScopedProxyFactoryBean}.
43+
* {@link BeanRegistrationAotProcessor} for {@link ScopedProxyFactoryBean}.
4444
*
4545
* @author Stephane Nicoll
4646
* @author Phillip Webb
4747
* @since 6.0
4848
*/
49-
class ScopedProxyBeanRegistrationCodeFragmentsCustomizer
50-
implements BeanRegistrationCodeFragmentsCustomizer {
49+
class ScopedProxyBeanRegistrationAotProcessor
50+
implements BeanRegistrationAotProcessor {
5151

5252
private static final Log logger = LogFactory
53-
.getLog(ScopedProxyBeanRegistrationCodeFragmentsCustomizer.class);
53+
.getLog(ScopedProxyBeanRegistrationAotProcessor.class);
5454

5555

5656
@Override
57-
public BeanRegistrationCodeFragments customizeBeanRegistrationCodeFragments(
58-
RegisteredBean registeredBean, BeanRegistrationCodeFragments codeFragments) {
59-
57+
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
6058
Class<?> beanType = registeredBean.getBeanType().toClass();
61-
if (!beanType.equals(ScopedProxyFactoryBean.class)) {
62-
return codeFragments;
63-
}
64-
String targetBeanName = getTargetBeanName(
65-
registeredBean.getMergedBeanDefinition());
66-
BeanDefinition targetBeanDefinition = getTargetBeanDefinition(
67-
registeredBean.getBeanFactory(), targetBeanName);
68-
if (targetBeanDefinition == null) {
69-
logger.warn("Could not handle " + ScopedProxyFactoryBean.class.getSimpleName()
70-
+ ": no target bean definition found with name " + targetBeanName);
71-
return codeFragments;
59+
if (beanType.equals(ScopedProxyFactoryBean.class)) {
60+
String targetBeanName = getTargetBeanName(
61+
registeredBean.getMergedBeanDefinition());
62+
BeanDefinition targetBeanDefinition = getTargetBeanDefinition(
63+
registeredBean.getBeanFactory(), targetBeanName);
64+
if (targetBeanDefinition == null) {
65+
logger.warn("Could not handle " + ScopedProxyFactoryBean.class.getSimpleName()
66+
+ ": no target bean definition found with name " + targetBeanName);
67+
return null;
68+
}
69+
return BeanRegistrationAotContribution.ofBeanRegistrationCodeFragmentsCustomizer(codeFragments ->
70+
new ScopedProxyBeanRegistrationCodeFragments(codeFragments, registeredBean,
71+
targetBeanName, targetBeanDefinition));
7272
}
73-
return new ScopedProxyBeanRegistrationCodeFragments(codeFragments, registeredBean,
74-
targetBeanName, targetBeanDefinition);
73+
return null;
7574
}
7675

7776
@Nullable
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
org.springframework.beans.factory.aot.registration.BeanRegistrationCodeFragmentsCustomizer=\
2-
org.springframework.aop.scope.ScopedProxyBeanRegistrationCodeFragmentsCustomizer
1+
org.springframework.beans.factory.aot.registration.BeanRegistrationAotProcessor=\
2+
org.springframework.aop.scope.ScopedProxyBeanRegistrationAotProcessor
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,13 @@
5050
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
5151

5252
/**
53-
* Tests for {@link ScopedProxyBeanRegistrationCodeFragmentsCustomizer}.
53+
* Tests for {@link ScopedProxyBeanRegistrationAotProcessor}.
5454
*
5555
* @author Stephane Nicoll
5656
* @author Phillip Webb
5757
* @since 6.0
5858
*/
59-
class ScopedProxyBeanRegistrationCodeFragmentsCustomizerTests {
59+
class ScopedProxyBeanRegistrationAotProcessorTests {
6060

6161
private DefaultListableBeanFactory beanFactory;
6262

spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGenerator.java

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -56,30 +56,25 @@ class BeanDefinitionMethodGenerator {
5656

5757
private final List<BeanRegistrationAotContribution> aotContributions;
5858

59-
private final List<BeanRegistrationCodeFragmentsCustomizer> codeFragmentsCustomizers;
60-
6159

6260
/**
6361
* Create a new {@link BeanDefinitionMethodGenerator} instance.
6462
* @param methodGeneratorFactory the method generator factory
6563
* @param registeredBean the registered bean
6664
* @param innerBeanPropertyName the inner bean property name
6765
* @param aotContributions the AOT contributions
68-
* @param codeFragmentsCustomizers the code fragments customizers
6966
*/
7067
BeanDefinitionMethodGenerator(
7168
BeanDefinitionMethodGeneratorFactory methodGeneratorFactory,
7269
RegisteredBean registeredBean, @Nullable String innerBeanPropertyName,
73-
List<BeanRegistrationAotContribution> aotContributions,
74-
List<BeanRegistrationCodeFragmentsCustomizer> codeFragmentsCustomizers) {
70+
List<BeanRegistrationAotContribution> aotContributions) {
7571

7672
this.methodGeneratorFactory = methodGeneratorFactory;
7773
this.registeredBean = registeredBean;
7874
this.constructorOrFactoryMethod = ConstructorOrFactoryMethodResolver
7975
.resolve(registeredBean);
8076
this.innerBeanPropertyName = innerBeanPropertyName;
8177
this.aotContributions = aotContributions;
82-
this.codeFragmentsCustomizers = codeFragmentsCustomizers;
8378
}
8479

8580
/**
@@ -92,8 +87,7 @@ class BeanDefinitionMethodGenerator {
9287
MethodReference generateBeanDefinitionMethod(GenerationContext generationContext,
9388
BeanRegistrationsCode beanRegistrationsCode) {
9489

95-
BeanRegistrationCodeFragments codeFragments = getCodeFragments(
96-
beanRegistrationsCode);
90+
BeanRegistrationCodeFragments codeFragments = getCodeFragments(beanRegistrationsCode);
9791
Class<?> target = codeFragments.getTarget(this.registeredBean,
9892
this.constructorOrFactoryMethod);
9993
if (!target.getName().startsWith("java.")) {
@@ -115,7 +109,17 @@ MethodReference generateBeanDefinitionMethod(GenerationContext generationContext
115109
Modifier.PRIVATE);
116110
return MethodReference.ofStatic(beanRegistrationsCode.getClassName(),
117111
generatedMethod.getName().toString());
112+
}
113+
114+
private BeanRegistrationCodeFragments getCodeFragments(
115+
BeanRegistrationsCode beanRegistrationsCode) {
118116

117+
BeanRegistrationCodeFragments codeFragments = new DefaultBeanRegistrationCodeFragments(
118+
beanRegistrationsCode, this.registeredBean, this.methodGeneratorFactory);
119+
for (BeanRegistrationAotContribution aotContribution : this.aotContributions) {
120+
codeFragments = aotContribution.customizeBeanRegistrationCodeFragments(codeFragments);
121+
}
122+
return codeFragments;
119123
}
120124

121125
private GeneratedMethod generateBeanDefinitionMethod(
@@ -126,8 +130,7 @@ private GeneratedMethod generateBeanDefinitionMethod(
126130
BeanRegistrationCodeGenerator codeGenerator = new BeanRegistrationCodeGenerator(
127131
className, methodGenerator, this.registeredBean,
128132
this.constructorOrFactoryMethod, codeFragments);
129-
GeneratedMethod method = methodGenerator.generateMethod("get", "bean",
130-
"definition");
133+
GeneratedMethod method = methodGenerator.generateMethod("get", "bean", "definition");
131134
this.aotContributions.forEach(aotContribution -> aotContribution
132135
.applyTo(generationContext, codeGenerator));
133136
return method.using(builder -> {
@@ -140,18 +143,6 @@ private GeneratedMethod generateBeanDefinitionMethod(
140143
});
141144
}
142145

143-
private BeanRegistrationCodeFragments getCodeFragments(
144-
BeanRegistrationsCode beanRegistrationsCode) {
145-
146-
BeanRegistrationCodeFragments codeFragments = new DefaultBeanRegistrationCodeFragments(
147-
beanRegistrationsCode, this.registeredBean, this.methodGeneratorFactory);
148-
for (BeanRegistrationCodeFragmentsCustomizer customizer : this.codeFragmentsCustomizers) {
149-
codeFragments = customizer.customizeBeanRegistrationCodeFragments(
150-
this.registeredBean, codeFragments);
151-
}
152-
return codeFragments;
153-
}
154-
155146
private String getName() {
156147
if (this.innerBeanPropertyName != null) {
157148
return this.innerBeanPropertyName;

spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorFactory.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,6 @@ class BeanDefinitionMethodGeneratorFactory {
4747

4848
private final List<BeanRegistrationExcludeFilter> excludeFilters;
4949

50-
private final List<BeanRegistrationCodeFragmentsCustomizer> codeGenerationCustomizers;
51-
5250

5351
/**
5452
* Create a new {@link BeanDefinitionMethodGeneratorFactory} backed by the
@@ -67,8 +65,6 @@ class BeanDefinitionMethodGeneratorFactory {
6765
BeanDefinitionMethodGeneratorFactory(AotFactoriesLoader loader) {
6866
this.aotProcessors = loader.load(BeanRegistrationAotProcessor.class);
6967
this.excludeFilters = loader.load(BeanRegistrationExcludeFilter.class);
70-
this.codeGenerationCustomizers = loader
71-
.load(BeanRegistrationCodeFragmentsCustomizer.class);
7268
}
7369

7470

@@ -92,7 +88,7 @@ BeanDefinitionMethodGenerator getBeanDefinitionMethodGenerator(
9288
List<BeanRegistrationAotContribution> contributions = getAotContributions(
9389
registeredBean);
9490
return new BeanDefinitionMethodGenerator(this, registeredBean,
95-
innerBeanPropertyName, contributions, this.codeGenerationCustomizers);
91+
innerBeanPropertyName, contributions);
9692
}
9793

9894
private boolean isExcluded(RegisteredBean registeredBean) {

spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationAotContribution.java

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@
1616

1717
package org.springframework.beans.factory.aot;
1818

19+
import java.util.function.UnaryOperator;
20+
1921
import org.springframework.aot.generate.GenerationContext;
22+
import org.springframework.util.Assert;
2023

2124
/**
2225
* AOT contribution from a {@link BeanRegistrationAotProcessor} used to register
@@ -29,6 +32,19 @@
2932
@FunctionalInterface
3033
public interface BeanRegistrationAotContribution {
3134

35+
/**
36+
* Customize the {@link BeanRegistrationCodeFragments} that will be used to
37+
* generate the bean registration code. Custom code fragments can be used if
38+
* default code generation isn't suitable.
39+
* @param codeFragments the existing code fragments
40+
* @return the code fragments to use, may be the original instance or a
41+
* wrapper
42+
*/
43+
default BeanRegistrationCodeFragments customizeBeanRegistrationCodeFragments(
44+
BeanRegistrationCodeFragments codeFragments) {
45+
return codeFragments;
46+
}
47+
3248
/**
3349
* Apply this contribution to the given {@link BeanRegistrationCode}.
3450
* @param generationContext the active generation context
@@ -37,4 +53,33 @@ public interface BeanRegistrationAotContribution {
3753
void applyTo(GenerationContext generationContext,
3854
BeanRegistrationCode beanRegistrationCode);
3955

56+
/**
57+
* Factory method that can be used to create a
58+
* {@link BeanRegistrationAotContribution} that applies the given
59+
* {@link BeanRegistrationCodeFragments} customizer.
60+
* @param beanRegistrationCodeFragmentsCustomizer the
61+
* {@link BeanRegistrationCodeFragments} customizer
62+
* @return a new {@link BeanRegistrationAotContribution} instance
63+
* @see #customizeBeanRegistrationCodeFragments(BeanRegistrationCodeFragments)
64+
*/
65+
static BeanRegistrationAotContribution ofBeanRegistrationCodeFragmentsCustomizer(
66+
UnaryOperator<BeanRegistrationCodeFragments> beanRegistrationCodeFragmentsCustomizer) {
67+
Assert.notNull(beanRegistrationCodeFragmentsCustomizer,
68+
"BeanRegistrationCodeFragmentsCustomizer must not be null");
69+
return new BeanRegistrationAotContribution() {
70+
71+
@Override
72+
public BeanRegistrationCodeFragments customizeBeanRegistrationCodeFragments(
73+
BeanRegistrationCodeFragments codeFragments) {
74+
return beanRegistrationCodeFragmentsCustomizer.apply(codeFragments);
75+
}
76+
77+
@Override
78+
public void applyTo(GenerationContext generationContext,
79+
BeanRegistrationCode beanRegistrationCode) {
80+
}
81+
82+
};
83+
}
84+
4085
}

spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationCodeFragmentsCustomizer.java

Lines changed: 0 additions & 45 deletions
This file was deleted.

spring-beans/src/main/java/org/springframework/beans/factory/aot/BeanRegistrationCodeGenerator.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,7 @@ CodeBlock generateCode(GenerationContext generationContext) {
8989
CodeBlock instanceSupplierCode = this.codeFragments.generateInstanceSupplierCode(
9090
generationContext, this, this.constructorOrFactoryMethod,
9191
this.instancePostProcessors.isEmpty());
92-
builder.add(
93-
this.codeFragments.generateSetBeanInstanceSupplierCode(generationContext,
92+
builder.add(this.codeFragments.generateSetBeanInstanceSupplierCode(generationContext,
9493
this, instanceSupplierCode, this.instancePostProcessors));
9594
builder.add(this.codeFragments.generateReturnCode(generationContext, this));
9695
return builder.build();

spring-beans/src/test/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanRegistrationAotContributionTests.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -182,11 +182,6 @@ private static class MockBeanRegistrationCode implements BeanRegistrationCode {
182182

183183
private final List<MethodReference> instancePostProcessors = new ArrayList<>();
184184

185-
@Override
186-
public void addInstancePostProcessor(MethodReference methodReference) {
187-
this.instancePostProcessors.add(methodReference);
188-
}
189-
190185
@Override
191186
public ClassName getClassName() {
192187
return null;
@@ -197,6 +192,11 @@ public MethodGenerator getMethodGenerator() {
197192
return null;
198193
}
199194

195+
@Override
196+
public void addInstancePostProcessor(MethodReference methodReference) {
197+
this.instancePostProcessors.add(methodReference);
198+
}
199+
200200
}
201201

202202
}

0 commit comments

Comments
 (0)