Skip to content

Commit fcb6baf

Browse files
committed
All MethodReference to support a more flexible signature
Closes gh-29005
2 parents 649c2f5 + 2b45fd4 commit fcb6baf

File tree

27 files changed

+683
-466
lines changed

27 files changed

+683
-466
lines changed

spring-aop/src/main/java/org/springframework/aop/scope/ScopedProxyBeanRegistrationAotProcessor.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,8 @@ public CodeBlock generateInstanceSupplierCode(GenerationContext generationContex
163163
method.addStatement("return ($T) factory.getObject()",
164164
beanClass);
165165
});
166-
return CodeBlock.of("$T.of($T::$L)", InstanceSupplier.class,
167-
beanRegistrationCode.getClassName(), generatedMethod.getName());
166+
return CodeBlock.of("$T.of($L)", InstanceSupplier.class,
167+
generatedMethod.toMethodReference().toCodeBlock());
168168
}
169169

170170
}

spring-aop/src/test/java/org/springframework/aop/scope/ScopedProxyBeanRegistrationAotProcessorTests.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
import org.springframework.aop.framework.AopInfrastructureBean;
2828
import org.springframework.aot.generate.MethodReference;
29+
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
2930
import org.springframework.aot.test.generate.TestGenerationContext;
3031
import org.springframework.aot.test.generate.compile.Compiled;
3132
import org.springframework.aot.test.generate.compile.TestCompiler;
@@ -139,11 +140,14 @@ private void compile(BiConsumer<DefaultListableBeanFactory, Compiled> result) {
139140
MethodReference methodReference = this.beanFactoryInitializationCode
140141
.getInitializers().get(0);
141142
this.beanFactoryInitializationCode.getTypeBuilder().set(type -> {
143+
CodeBlock methodInvocation = methodReference.toInvokeCodeBlock(
144+
ArgumentCodeGenerator.of(DefaultListableBeanFactory.class, "beanFactory"),
145+
this.beanFactoryInitializationCode.getClassName());
142146
type.addModifiers(Modifier.PUBLIC);
143147
type.addSuperinterface(ParameterizedTypeName.get(Consumer.class, DefaultListableBeanFactory.class));
144148
type.addMethod(MethodSpec.methodBuilder("accept").addModifiers(Modifier.PUBLIC)
145149
.addParameter(DefaultListableBeanFactory.class, "beanFactory")
146-
.addStatement(methodReference.toInvokeCodeBlock(CodeBlock.of("beanFactory")))
150+
.addStatement(methodInvocation)
147151
.build());
148152
});
149153
this.generationContext.writeGeneratedContent();

spring-beans/src/main/java/org/springframework/beans/factory/annotation/AutowiredAnnotationBeanPostProcessor.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444
import org.springframework.aot.generate.GeneratedClass;
4545
import org.springframework.aot.generate.GeneratedMethod;
4646
import org.springframework.aot.generate.GenerationContext;
47-
import org.springframework.aot.generate.MethodReference;
4847
import org.springframework.aot.hint.ExecutableMode;
4948
import org.springframework.aot.hint.RuntimeHints;
5049
import org.springframework.beans.BeanUtils;
@@ -944,8 +943,7 @@ public void applyTo(GenerationContext generationContext,
944943
method.returns(this.target);
945944
method.addCode(generateMethodCode(generationContext.getRuntimeHints()));
946945
});
947-
beanRegistrationCode.addInstancePostProcessor(
948-
MethodReference.ofStatic(generatedClass.getName(), generateMethod.getName()));
946+
beanRegistrationCode.addInstancePostProcessor(generateMethod.toMethodReference());
949947

950948
if (this.candidateResolver != null) {
951949
registerHints(generationContext.getRuntimeHints());

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

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,16 +107,14 @@ MethodReference generateBeanDefinitionMethod(GenerationContext generationContext
107107
GeneratedMethod generatedMethod = generateBeanDefinitionMethod(
108108
generationContext, generatedClass.getName(), generatedMethods,
109109
codeFragments, Modifier.PUBLIC);
110-
return MethodReference.ofStatic(generatedClass.getName(),
111-
generatedMethod.getName());
110+
return generatedMethod.toMethodReference();
112111
}
113112
GeneratedMethods generatedMethods = beanRegistrationsCode.getMethods()
114113
.withPrefix(getName());
115114
GeneratedMethod generatedMethod = generateBeanDefinitionMethod(generationContext,
116115
beanRegistrationsCode.getClassName(), generatedMethods, codeFragments,
117116
Modifier.PRIVATE);
118-
return MethodReference.ofStatic(beanRegistrationsCode.getClassName(),
119-
generatedMethod.getName());
117+
return generatedMethod.toMethodReference();
120118
}
121119

122120
private BeanRegistrationCodeFragments getCodeFragments(GenerationContext generationContext,

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
* perform bean factory initialization.
2525
*
2626
* @author Phillip Webb
27+
* @author Stephane Nicoll
2728
* @since 6.0
2829
* @see BeanFactoryInitializationAotContribution
2930
*/
@@ -41,10 +42,16 @@ public interface BeanFactoryInitializationCode {
4142
GeneratedMethods getMethods();
4243

4344
/**
44-
* Add an initializer method call.
45-
* @param methodReference a reference to the initialize method to call. The
46-
* referenced method must have the same functional signature as
47-
* {@code Consumer<DefaultListableBeanFactory>}.
45+
* Add an initializer method call. An initializer can use a flexible signature,
46+
* using any of the following:
47+
* <ul>
48+
* <li>{@code DefaultListableBeanFactory}, or {@code ConfigurableListableBeanFactory}
49+
* to use the bean factory.</li>
50+
* <li>{@code ConfigurableEnvironment} or {@code Environment} to access the
51+
* environment.</li>
52+
* <li>{@code ResourceLoader} to load resources.</li>
53+
* </ul>
54+
* @param methodReference a reference to the initialize method to call.
4855
*/
4956
void addInitializer(MethodReference methodReference);
5057

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

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.springframework.aot.generate.GeneratedMethods;
2626
import org.springframework.aot.generate.GenerationContext;
2727
import org.springframework.aot.generate.MethodReference;
28+
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
2829
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
2930
import org.springframework.javapoet.ClassName;
3031
import org.springframework.javapoet.CodeBlock;
@@ -65,8 +66,7 @@ public void applyTo(GenerationContext generationContext,
6566
BeanRegistrationsCodeGenerator codeGenerator = new BeanRegistrationsCodeGenerator(generatedClass);
6667
GeneratedMethod generatedMethod = codeGenerator.getMethods().add("registerBeanDefinitions", method ->
6768
generateRegisterMethod(method, generationContext, codeGenerator));
68-
beanFactoryInitializationCode.addInitializer(
69-
MethodReference.of(generatedClass.getName(), generatedMethod.getName()));
69+
beanFactoryInitializationCode.addInitializer(generatedMethod.toMethodReference());
7070
}
7171

7272
private void generateRegisterMethod(MethodSpec.Builder method,
@@ -82,9 +82,11 @@ private void generateRegisterMethod(MethodSpec.Builder method,
8282
MethodReference beanDefinitionMethod = beanDefinitionMethodGenerator
8383
.generateBeanDefinitionMethod(generationContext,
8484
beanRegistrationsCode);
85+
CodeBlock methodInvocation = beanDefinitionMethod.toInvokeCodeBlock(
86+
ArgumentCodeGenerator.none(), beanRegistrationsCode.getClassName());
8587
code.addStatement("$L.registerBeanDefinition($S, $L)",
8688
BEAN_FACTORY_PARAMETER_NAME, beanName,
87-
beanDefinitionMethod.toInvokeCodeBlock());
89+
methodInvocation);
8890
});
8991
method.addCode(code.build());
9092
}

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.springframework.aot.generate.AccessVisibility;
2525
import org.springframework.aot.generate.GenerationContext;
2626
import org.springframework.aot.generate.MethodReference;
27+
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
2728
import org.springframework.beans.factory.FactoryBean;
2829
import org.springframework.beans.factory.config.BeanDefinition;
2930
import org.springframework.beans.factory.config.BeanDefinitionHolder;
@@ -156,7 +157,7 @@ protected CodeBlock generateValueCode(GenerationContext generationContext,
156157
MethodReference generatedMethod = methodGenerator
157158
.generateBeanDefinitionMethod(generationContext,
158159
this.beanRegistrationsCode);
159-
return generatedMethod.toInvokeCodeBlock();
160+
return generatedMethod.toInvokeCodeBlock(ArgumentCodeGenerator.none());
160161
}
161162
return null;
162163
}

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
import org.springframework.aot.generate.GeneratedMethod;
2929
import org.springframework.aot.generate.GeneratedMethods;
3030
import org.springframework.aot.generate.GenerationContext;
31+
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
3132
import org.springframework.aot.hint.ExecutableMode;
3233
import org.springframework.beans.factory.support.InstanceSupplier;
3334
import org.springframework.beans.factory.support.RegisteredBean;
@@ -296,8 +297,9 @@ private CodeBlock generateNewInstanceCodeForMethod(boolean dependsOnBean,
296297
REGISTERED_BEAN_PARAMETER_NAME, declaringClass, factoryMethodName, args);
297298
}
298299

299-
private CodeBlock generateReturnStatement(GeneratedMethod getInstanceMethod) {
300-
return CodeBlock.of("$T.$L()", this.className, getInstanceMethod.getName());
300+
private CodeBlock generateReturnStatement(GeneratedMethod generatedMethod) {
301+
return generatedMethod.toMethodReference().toInvokeCodeBlock(
302+
ArgumentCodeGenerator.none(), this.className);
301303
}
302304

303305
private CodeBlock generateWithGeneratorCode(boolean hasArguments, CodeBlock newInstance) {

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.junit.jupiter.api.Test;
2525

2626
import org.springframework.aot.generate.MethodReference;
27+
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
2728
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
2829
import org.springframework.aot.test.generate.TestGenerationContext;
2930
import org.springframework.aot.test.generate.compile.CompileWithTargetClassAccess;
@@ -161,13 +162,16 @@ private void compile(RegisteredBean registeredBean,
161162
Class<?> target = registeredBean.getBeanClass();
162163
MethodReference methodReference = this.beanRegistrationCode.getInstancePostProcessors().get(0);
163164
this.beanRegistrationCode.getTypeBuilder().set(type -> {
165+
CodeBlock methodInvocation = methodReference.toInvokeCodeBlock(
166+
ArgumentCodeGenerator.of(RegisteredBean.class, "registeredBean").and(target, "instance"),
167+
this.beanRegistrationCode.getClassName());
164168
type.addModifiers(Modifier.PUBLIC);
165169
type.addSuperinterface(ParameterizedTypeName.get(BiFunction.class, RegisteredBean.class, target, target));
166170
type.addMethod(MethodSpec.methodBuilder("apply")
167171
.addModifiers(Modifier.PUBLIC)
168172
.addParameter(RegisteredBean.class, "registeredBean")
169173
.addParameter(target, "instance").returns(target)
170-
.addStatement("return $L", methodReference.toInvokeCodeBlock(CodeBlock.of("registeredBean"), CodeBlock.of("instance")))
174+
.addStatement("return $L", methodInvocation)
171175
.build());
172176

173177
});

spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanDefinitionMethodGeneratorTests.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import org.springframework.aot.generate.GeneratedMethod;
3131
import org.springframework.aot.generate.GenerationContext;
3232
import org.springframework.aot.generate.MethodReference;
33+
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
3334
import org.springframework.aot.test.generate.TestGenerationContext;
3435
import org.springframework.aot.test.generate.compile.CompileWithTargetClassAccess;
3536
import org.springframework.aot.test.generate.compile.Compiled;
@@ -129,8 +130,7 @@ void generateBeanDefinitionMethodWhenHasInstancePostProcessorGeneratesMethod() {
129130
.addParameter(RegisteredBean.class, "registeredBean")
130131
.addParameter(TestBean.class, "testBean")
131132
.returns(TestBean.class).addCode("return new $T($S);", TestBean.class, "postprocessed"));
132-
beanRegistrationCode.addInstancePostProcessor(MethodReference.ofStatic(
133-
beanRegistrationCode.getClassName(), generatedMethod.getName()));
133+
beanRegistrationCode.addInstancePostProcessor(generatedMethod.toMethodReference());
134134
};
135135
List<BeanRegistrationAotContribution> aotContributions = Collections
136136
.singletonList(aotContribution);
@@ -167,8 +167,7 @@ void generateBeanDefinitionMethodWhenHasInstancePostProcessorAndFactoryMethodGen
167167
.addParameter(RegisteredBean.class, "registeredBean")
168168
.addParameter(TestBean.class, "testBean")
169169
.returns(TestBean.class).addCode("return new $T($S);", TestBean.class, "postprocessed"));
170-
beanRegistrationCode.addInstancePostProcessor(MethodReference.ofStatic(
171-
beanRegistrationCode.getClassName(), generatedMethod.getName()));
170+
beanRegistrationCode.addInstancePostProcessor(generatedMethod.toMethodReference());
172171
};
173172
List<BeanRegistrationAotContribution> aotContributions = Collections
174173
.singletonList(aotContribution);
@@ -416,12 +415,14 @@ private RegisteredBean registerBean(RootBeanDefinition beanDefinition) {
416415
private void compile(MethodReference method,
417416
BiConsumer<RootBeanDefinition, Compiled> result) {
418417
this.beanRegistrationsCode.getTypeBuilder().set(type -> {
418+
CodeBlock methodInvocation = method.toInvokeCodeBlock(ArgumentCodeGenerator.none(),
419+
this.beanRegistrationsCode.getClassName());
419420
type.addModifiers(Modifier.PUBLIC);
420421
type.addSuperinterface(ParameterizedTypeName.get(Supplier.class, BeanDefinition.class));
421422
type.addMethod(MethodSpec.methodBuilder("get")
422423
.addModifiers(Modifier.PUBLIC)
423424
.returns(BeanDefinition.class)
424-
.addCode("return $L;", method.toInvokeCodeBlock()).build());
425+
.addCode("return $L;", methodInvocation).build());
425426
});
426427
this.generationContext.writeGeneratedContent();
427428
TestCompiler.forSystem().withFiles(this.generationContext.getGeneratedFiles()).compile(compiled ->

spring-beans/src/test/java/org/springframework/beans/factory/aot/BeanRegistrationsAotContributionTests.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.springframework.aot.generate.ClassNameGenerator;
3232
import org.springframework.aot.generate.GenerationContext;
3333
import org.springframework.aot.generate.MethodReference;
34+
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
3435
import org.springframework.aot.test.generate.TestGenerationContext;
3536
import org.springframework.aot.test.generate.TestTarget;
3637
import org.springframework.aot.test.generate.compile.Compiled;
@@ -155,11 +156,14 @@ private void compile(
155156
MethodReference methodReference = this.beanFactoryInitializationCode
156157
.getInitializers().get(0);
157158
this.beanFactoryInitializationCode.getTypeBuilder().set(type -> {
159+
CodeBlock methodInvocation = methodReference.toInvokeCodeBlock(
160+
ArgumentCodeGenerator.of(DefaultListableBeanFactory.class, "beanFactory"),
161+
this.beanFactoryInitializationCode.getClassName());
158162
type.addModifiers(Modifier.PUBLIC);
159163
type.addSuperinterface(ParameterizedTypeName.get(Consumer.class, DefaultListableBeanFactory.class));
160164
type.addMethod(MethodSpec.methodBuilder("accept").addModifiers(Modifier.PUBLIC)
161165
.addParameter(DefaultListableBeanFactory.class, "beanFactory")
162-
.addStatement(methodReference.toInvokeCodeBlock(CodeBlock.of("beanFactory")))
166+
.addStatement(methodInvocation)
163167
.build());
164168
});
165169
this.generationContext.writeGeneratedContent();

spring-beans/src/testFixtures/java/org/springframework/beans/testfixture/beans/factory/aot/MockBeanFactoryInitializationCode.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import org.springframework.aot.generate.GenerationContext;
2626
import org.springframework.aot.generate.MethodReference;
2727
import org.springframework.beans.factory.aot.BeanFactoryInitializationCode;
28+
import org.springframework.javapoet.ClassName;
2829

2930
/**
3031
* Mock {@link BeanFactoryInitializationCode} implementation.
@@ -46,6 +47,9 @@ public MockBeanFactoryInitializationCode(GenerationContext generationContext) {
4647
.addForFeature("TestCode", this.typeBuilder);
4748
}
4849

50+
public ClassName getClassName() {
51+
return this.generatedClass.getName();
52+
}
4953

5054
public DeferredTypeBuilder getTypeBuilder() {
5155
return this.typeBuilder;

spring-context/src/main/java/org/springframework/context/annotation/ConfigurationClassPostProcessor.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333
import org.springframework.aop.framework.autoproxy.AutoProxyUtils;
3434
import org.springframework.aot.generate.GeneratedMethod;
3535
import org.springframework.aot.generate.GenerationContext;
36-
import org.springframework.aot.generate.MethodReference;
3736
import org.springframework.aot.hint.ResourceHints;
3837
import org.springframework.aot.hint.TypeReference;
3938
import org.springframework.beans.PropertyValues;
@@ -536,7 +535,7 @@ public void applyTo(GenerationContext generationContext,
536535
.add("addImportAwareBeanPostProcessors", method ->
537536
generateAddPostProcessorMethod(method, mappings));
538537
beanFactoryInitializationCode
539-
.addInitializer(MethodReference.of(generatedMethod.getName()));
538+
.addInitializer(generatedMethod.toMethodReference());
540539
ResourceHints hints = generationContext.getRuntimeHints().resources();
541540
mappings.forEach(
542541
(target, from) -> hints.registerType(TypeReference.of(from)));

spring-context/src/main/java/org/springframework/context/aot/ApplicationContextInitializationCodeGenerator.java

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,32 @@
1818

1919
import java.util.ArrayList;
2020
import java.util.List;
21+
import java.util.function.Function;
2122

2223
import javax.lang.model.element.Modifier;
2324

2425
import org.springframework.aot.generate.GeneratedClass;
2526
import org.springframework.aot.generate.GeneratedMethods;
2627
import org.springframework.aot.generate.GenerationContext;
2728
import org.springframework.aot.generate.MethodReference;
29+
import org.springframework.aot.generate.MethodReference.ArgumentCodeGenerator;
2830
import org.springframework.beans.factory.aot.BeanFactoryInitializationCode;
31+
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
2932
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
3033
import org.springframework.context.ApplicationContextInitializer;
3134
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
3235
import org.springframework.context.support.GenericApplicationContext;
3336
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
37+
import org.springframework.core.env.ConfigurableEnvironment;
38+
import org.springframework.core.env.Environment;
39+
import org.springframework.core.io.ResourceLoader;
40+
import org.springframework.javapoet.ClassName;
3441
import org.springframework.javapoet.CodeBlock;
3542
import org.springframework.javapoet.MethodSpec;
3643
import org.springframework.javapoet.ParameterizedTypeName;
44+
import org.springframework.javapoet.TypeName;
3745
import org.springframework.javapoet.TypeSpec;
46+
import org.springframework.lang.Nullable;
3847

3948
/**
4049
* Internal code generator to create the {@link ApplicationContextInitializer}.
@@ -88,12 +97,17 @@ private CodeBlock generateInitializeCode() {
8897
BEAN_FACTORY_VARIABLE, ContextAnnotationAutowireCandidateResolver.class);
8998
code.addStatement("$L.setDependencyComparator($T.INSTANCE)",
9099
BEAN_FACTORY_VARIABLE, AnnotationAwareOrderComparator.class);
100+
ArgumentCodeGenerator argCodeGenerator = createInitializerMethodArgumentCodeGenerator();
91101
for (MethodReference initializer : this.initializers) {
92-
code.addStatement(initializer.toInvokeCodeBlock(CodeBlock.of(BEAN_FACTORY_VARIABLE)));
102+
code.addStatement(initializer.toInvokeCodeBlock(argCodeGenerator, this.generatedClass.getName()));
93103
}
94104
return code.build();
95105
}
96106

107+
static ArgumentCodeGenerator createInitializerMethodArgumentCodeGenerator() {
108+
return ArgumentCodeGenerator.from(new InitializerMethodArgumentCodeGenerator());
109+
}
110+
97111
GeneratedClass getGeneratedClass() {
98112
return this.generatedClass;
99113
}
@@ -108,4 +122,30 @@ public void addInitializer(MethodReference methodReference) {
108122
this.initializers.add(methodReference);
109123
}
110124

125+
private static class InitializerMethodArgumentCodeGenerator implements Function<TypeName, CodeBlock> {
126+
127+
@Override
128+
@Nullable
129+
public CodeBlock apply(TypeName typeName) {
130+
return (typeName instanceof ClassName className ? apply(className) : null);
131+
}
132+
133+
@Nullable
134+
private CodeBlock apply(ClassName className) {
135+
String name = className.canonicalName();
136+
if (name.equals(DefaultListableBeanFactory.class.getName())
137+
|| name.equals(ConfigurableListableBeanFactory.class.getName())) {
138+
return CodeBlock.of(BEAN_FACTORY_VARIABLE);
139+
}
140+
else if (name.equals(ConfigurableEnvironment.class.getName())
141+
|| name.equals(Environment.class.getName())) {
142+
return CodeBlock.of("$L.getConfigurableEnvironment()", APPLICATION_CONTEXT_VARIABLE);
143+
}
144+
else if (name.equals(ResourceLoader.class.getName())) {
145+
return CodeBlock.of(APPLICATION_CONTEXT_VARIABLE);
146+
}
147+
return null;
148+
}
149+
}
150+
111151
}

0 commit comments

Comments
 (0)