33
33
import org .springframework .beans .factory .support .RegisteredBean ;
34
34
import org .springframework .javapoet .ClassName ;
35
35
import org .springframework .javapoet .CodeBlock ;
36
+ import org .springframework .javapoet .CodeBlock .Builder ;
36
37
import org .springframework .javapoet .MethodSpec ;
37
38
38
39
/**
@@ -51,6 +52,9 @@ class BeanRegistrationsAotContribution
51
52
52
53
private static final String BEAN_FACTORY_PARAMETER_NAME = "beanFactory" ;
53
54
55
+ private static final ArgumentCodeGenerator argumentCodeGenerator = ArgumentCodeGenerator
56
+ .of (DefaultListableBeanFactory .class , BEAN_FACTORY_PARAMETER_NAME );
57
+
54
58
private final List <Registration > registrations ;
55
59
56
60
@@ -69,42 +73,15 @@ public void applyTo(GenerationContext generationContext,
69
73
type .addModifiers (Modifier .PUBLIC );
70
74
});
71
75
BeanRegistrationsCodeGenerator codeGenerator = new BeanRegistrationsCodeGenerator (generatedClass );
72
- GeneratedMethod generatedBeanDefinitionsMethod = codeGenerator . getMethods (). add ( "registerBeanDefinitions" , method ->
73
- generateRegisterBeanDefinitionsMethod ( method , generationContext , codeGenerator ) );
76
+ GeneratedMethod generatedBeanDefinitionsMethod = new BeanDefinitionsRegistrationGenerator (
77
+ generationContext , codeGenerator , this . registrations ). generateRegisterBeanDefinitionsMethod ( );
74
78
beanFactoryInitializationCode .addInitializer (generatedBeanDefinitionsMethod .toMethodReference ());
75
79
GeneratedMethod generatedAliasesMethod = codeGenerator .getMethods ().add ("registerAliases" ,
76
80
this ::generateRegisterAliasesMethod );
77
81
beanFactoryInitializationCode .addInitializer (generatedAliasesMethod .toMethodReference ());
78
82
generateRegisterHints (generationContext .getRuntimeHints (), this .registrations );
79
83
}
80
84
81
- private void generateRegisterBeanDefinitionsMethod (MethodSpec .Builder method ,
82
- GenerationContext generationContext , BeanRegistrationsCode beanRegistrationsCode ) {
83
-
84
- method .addJavadoc ("Register the bean definitions." );
85
- method .addModifiers (Modifier .PUBLIC );
86
- method .addParameter (DefaultListableBeanFactory .class , BEAN_FACTORY_PARAMETER_NAME );
87
- CodeBlock .Builder code = CodeBlock .builder ();
88
- this .registrations .forEach (registration -> {
89
- try {
90
- MethodReference beanDefinitionMethod = registration .methodGenerator
91
- .generateBeanDefinitionMethod (generationContext , beanRegistrationsCode );
92
- CodeBlock methodInvocation = beanDefinitionMethod .toInvokeCodeBlock (
93
- ArgumentCodeGenerator .none (), beanRegistrationsCode .getClassName ());
94
- code .addStatement ("$L.registerBeanDefinition($S, $L)" ,
95
- BEAN_FACTORY_PARAMETER_NAME , registration .beanName (), methodInvocation );
96
- }
97
- catch (AotException ex ) {
98
- throw ex ;
99
- }
100
- catch (Exception ex ) {
101
- throw new AotBeanProcessingException (registration .registeredBean ,
102
- "failed to generate code for bean definition" , ex );
103
- }
104
- });
105
- method .addCode (code .build ());
106
- }
107
-
108
85
private void generateRegisterAliasesMethod (MethodSpec .Builder method ) {
109
86
method .addJavadoc ("Register the aliases." );
110
87
method .addModifiers (Modifier .PUBLIC );
@@ -167,4 +144,89 @@ public GeneratedMethods getMethods() {
167
144
168
145
}
169
146
147
+ static final class BeanDefinitionsRegistrationGenerator {
148
+
149
+ private final GenerationContext generationContext ;
150
+
151
+ private final BeanRegistrationsCodeGenerator codeGenerator ;
152
+
153
+ private final List <Registration > registrations ;
154
+
155
+
156
+ BeanDefinitionsRegistrationGenerator (GenerationContext generationContext ,
157
+ BeanRegistrationsCodeGenerator codeGenerator , List <Registration > registrations ) {
158
+
159
+ this .generationContext = generationContext ;
160
+ this .codeGenerator = codeGenerator ;
161
+ this .registrations = registrations ;
162
+ }
163
+
164
+
165
+ GeneratedMethod generateRegisterBeanDefinitionsMethod () {
166
+ return this .codeGenerator .getMethods ().add ("registerBeanDefinitions" , method -> {
167
+ method .addJavadoc ("Register the bean definitions." );
168
+ method .addModifiers (Modifier .PUBLIC );
169
+ method .addParameter (DefaultListableBeanFactory .class , BEAN_FACTORY_PARAMETER_NAME );
170
+ if (this .registrations .size () <= 1000 ) {
171
+ generateRegisterBeanDefinitionMethods (method , this .registrations );
172
+ }
173
+ else {
174
+ Builder code = CodeBlock .builder ();
175
+ code .add ("// Registration is sliced to avoid exceeding size limit\n " );
176
+ int index = 0 ;
177
+ int end = 0 ;
178
+ while (end < this .registrations .size ()) {
179
+ int start = index * 1000 ;
180
+ end = Math .min (start + 1000 , this .registrations .size ());
181
+ GeneratedMethod sliceMethod = generateSliceMethod (start , end );
182
+ code .addStatement (sliceMethod .toMethodReference ().toInvokeCodeBlock (
183
+ argumentCodeGenerator , this .codeGenerator .getClassName ()));
184
+ index ++;
185
+ }
186
+ method .addCode (code .build ());
187
+ }
188
+ });
189
+ }
190
+
191
+ private GeneratedMethod generateSliceMethod (int start , int end ) {
192
+ String description = "Register the bean definitions from %s to %s." .formatted (start , end - 1 );
193
+ List <Registration > slice = this .registrations .subList (start , end );
194
+ return this .codeGenerator .getMethods ().add ("registerBeanDefinitions" , method -> {
195
+ method .addJavadoc (description );
196
+ method .addModifiers (Modifier .PRIVATE );
197
+ method .addParameter (DefaultListableBeanFactory .class , BEAN_FACTORY_PARAMETER_NAME );
198
+ generateRegisterBeanDefinitionMethods (method , slice );
199
+ });
200
+ }
201
+
202
+
203
+ private void generateRegisterBeanDefinitionMethods (MethodSpec .Builder method ,
204
+ Iterable <Registration > registrations ) {
205
+
206
+ CodeBlock .Builder code = CodeBlock .builder ();
207
+ registrations .forEach (registration -> {
208
+ try {
209
+ CodeBlock methodInvocation = generateBeanRegistration (registration );
210
+ code .addStatement ("$L.registerBeanDefinition($S, $L)" ,
211
+ BEAN_FACTORY_PARAMETER_NAME , registration .beanName (), methodInvocation );
212
+ }
213
+ catch (AotException ex ) {
214
+ throw ex ;
215
+ }
216
+ catch (Exception ex ) {
217
+ throw new AotBeanProcessingException (registration .registeredBean ,
218
+ "failed to generate code for bean definition" , ex );
219
+ }
220
+ });
221
+ method .addCode (code .build ());
222
+ }
223
+
224
+ private CodeBlock generateBeanRegistration (Registration registration ) {
225
+ MethodReference beanDefinitionMethod = registration .methodGenerator
226
+ .generateBeanDefinitionMethod (this .generationContext , this .codeGenerator );
227
+ return beanDefinitionMethod .toInvokeCodeBlock (
228
+ ArgumentCodeGenerator .none (), this .codeGenerator .getClassName ());
229
+ }
230
+ }
231
+
170
232
}
0 commit comments