Add custom code generation for bean definition property values
This commits allows ValueCodeGenerator$Delegate implementations to be loaded from `META-INF/spring/aot.factories` and considered for code generation of bean definition property values. This default behavior in DefaultBeanRegistrationCodeFragments can be customized as usual. Closes gh-31427
This commit is contained in:
@@ -97,15 +97,17 @@ class BeanDefinitionPropertiesCodeGenerator {
|
||||
|
||||
BeanDefinitionPropertiesCodeGenerator(RuntimeHints hints,
|
||||
Predicate<String> attributeFilter, GeneratedMethods generatedMethods,
|
||||
List<Delegate> additionalDelegates,
|
||||
BiFunction<String, Object, CodeBlock> customValueCodeGenerator) {
|
||||
|
||||
this.hints = hints;
|
||||
this.attributeFilter = attributeFilter;
|
||||
this.valueCodeGenerator = ValueCodeGenerator
|
||||
.with(new ValueCodeGeneratorDelegateAdapter(customValueCodeGenerator))
|
||||
.add(BeanDefinitionPropertyValueCodeGeneratorDelegates.INSTANCES)
|
||||
.add(ValueCodeGeneratorDelegates.INSTANCES)
|
||||
.scoped(generatedMethods);
|
||||
List<Delegate> allDelegates = new ArrayList<>();
|
||||
allDelegates.add((valueCodeGenerator, value) -> customValueCodeGenerator.apply(PropertyNamesStack.peek(), value));
|
||||
allDelegates.addAll(additionalDelegates);
|
||||
allDelegates.addAll(BeanDefinitionPropertyValueCodeGeneratorDelegates.INSTANCES);
|
||||
allDelegates.addAll(ValueCodeGeneratorDelegates.INSTANCES);
|
||||
this.valueCodeGenerator = ValueCodeGenerator.with(allDelegates).scoped(generatedMethods);
|
||||
}
|
||||
|
||||
|
||||
@@ -373,21 +375,6 @@ class BeanDefinitionPropertiesCodeGenerator {
|
||||
}
|
||||
|
||||
|
||||
static class ValueCodeGeneratorDelegateAdapter implements Delegate {
|
||||
|
||||
private final BiFunction<String, Object, CodeBlock> customValueCodeGenerator;
|
||||
|
||||
ValueCodeGeneratorDelegateAdapter(BiFunction<String, Object, CodeBlock> customValueCodeGenerator) {
|
||||
this.customValueCodeGenerator = customValueCodeGenerator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CodeBlock generateCode(ValueCodeGenerator valueCodeGenerator, Object value) {
|
||||
return this.customValueCodeGenerator.apply(PropertyNamesStack.peek(), value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class PropertyNamesStack {
|
||||
|
||||
private static final ThreadLocal<ArrayDeque<String>> threadLocal = ThreadLocal.withInitial(ArrayDeque::new);
|
||||
|
||||
@@ -28,7 +28,9 @@ import org.springframework.aot.generate.GenerationContext;
|
||||
import org.springframework.aot.generate.MethodReference;
|
||||
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
|
||||
import org.springframework.aot.generate.ValueCodeGenerator;
|
||||
import org.springframework.aot.generate.ValueCodeGenerator.Delegate;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.aot.AotServices.Loader;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||
import org.springframework.beans.factory.support.InstanceSupplier;
|
||||
@@ -171,12 +173,12 @@ class DefaultBeanRegistrationCodeFragments implements BeanRegistrationCodeFragme
|
||||
GenerationContext generationContext,
|
||||
BeanRegistrationCode beanRegistrationCode, RootBeanDefinition beanDefinition,
|
||||
Predicate<String> attributeFilter) {
|
||||
|
||||
return new BeanDefinitionPropertiesCodeGenerator(
|
||||
generationContext.getRuntimeHints(), attributeFilter,
|
||||
beanRegistrationCode.getMethods(),
|
||||
(name, value) -> generateValueCode(generationContext, name, value))
|
||||
.generateCode(beanDefinition);
|
||||
Loader loader = AotServices.factories(this.registeredBean.getBeanFactory().getBeanClassLoader());
|
||||
List<Delegate> additionalDelegates = loader.load(Delegate.class).asList();
|
||||
return new BeanDefinitionPropertiesCodeGenerator(generationContext.getRuntimeHints(),
|
||||
attributeFilter, beanRegistrationCode.getMethods(),
|
||||
additionalDelegates, (name, value) -> generateValueCode(generationContext, name, value)
|
||||
).generateCode(beanDefinition);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
Reference in New Issue
Block a user