29
29
import org .apache .commons .logging .Log ;
30
30
import org .apache .commons .logging .LogFactory ;
31
31
import org .jspecify .annotations .Nullable ;
32
-
33
- import org .springframework .aot .generate .ClassNameGenerator ;
34
32
import org .springframework .aot .generate .Generated ;
33
+ import org .springframework .aot .generate .GeneratedTypeReference ;
34
+ import org .springframework .aot .hint .TypeReference ;
35
35
import org .springframework .data .projection .ProjectionFactory ;
36
36
import org .springframework .data .repository .aot .generate .AotRepositoryFragmentMetadata .ConstructorArgument ;
37
37
import org .springframework .data .repository .core .RepositoryInformation ;
38
38
import org .springframework .data .repository .core .support .RepositoryComposition ;
39
39
import org .springframework .data .repository .core .support .RepositoryFragment ;
40
40
import org .springframework .data .repository .query .QueryMethod ;
41
41
import org .springframework .javapoet .ClassName ;
42
- import org .springframework .javapoet .FieldSpec ;
43
42
import org .springframework .javapoet .JavaFile ;
44
43
import org .springframework .javapoet .MethodSpec ;
45
44
import org .springframework .javapoet .TypeName ;
@@ -64,6 +63,8 @@ class AotRepositoryBuilder {
64
63
private @ Nullable Consumer <AotRepositoryConstructorBuilder > constructorCustomizer ;
65
64
private @ Nullable MethodContributorFactory methodContributorFactory ;
66
65
private Consumer <AotRepositoryClassBuilder > classCustomizer ;
66
+ private @ Nullable TypeReference targetClassName ;
67
+ private RepositoryConstructorBuilder constructorBuilder ;
67
68
68
69
private AotRepositoryBuilder (RepositoryInformation repositoryInformation , String moduleName ,
69
70
ProjectionFactory projectionFactory ) {
@@ -72,13 +73,9 @@ private AotRepositoryBuilder(RepositoryInformation repositoryInformation, String
72
73
this .moduleName = moduleName ;
73
74
this .projectionFactory = projectionFactory ;
74
75
75
- this .generationMetadata = new AotRepositoryFragmentMetadata (className ());
76
- this .generationMetadata .addField (FieldSpec
77
- .builder (TypeName .get (Log .class ), "logger" , Modifier .PRIVATE , Modifier .STATIC , Modifier .FINAL )
78
- .initializer ("$T.getLog($T.class)" , TypeName .get (LogFactory .class ), this .generationMetadata .getTargetTypeName ())
79
- .build ());
80
-
76
+ this .generationMetadata = new AotRepositoryFragmentMetadata ();
81
77
this .classCustomizer = (builder ) -> {};
78
+ this .constructorBuilder = new RepositoryConstructorBuilder (generationMetadata );
82
79
}
83
80
84
81
/**
@@ -131,15 +128,24 @@ public AotRepositoryBuilder withQueryMethodContributor(MethodContributorFactory
131
128
return this ;
132
129
}
133
130
134
- public AotBundle build () {
131
+ public AotRepositoryBuilder prepare (@ Nullable ClassName targetClassName ) {
132
+ if (targetClassName == null ) {
133
+ withTargetClassName (null );
134
+ } else {
135
+ withTargetClassName (GeneratedTypeReference .of (targetClassName ));
136
+ }
137
+ if (constructorCustomizer != null ) {
138
+ constructorCustomizer .accept (constructorBuilder );
139
+ }
140
+ return this ;
141
+ }
142
+
143
+ public AotBundle build (TypeSpec .Builder builder ) {
135
144
136
145
List <AotRepositoryMethod > methodMetadata = new ArrayList <>();
137
146
RepositoryComposition repositoryComposition = repositoryInformation .getRepositoryComposition ();
138
147
139
- // start creating the type
140
- TypeSpec .Builder builder = TypeSpec .classBuilder (this .generationMetadata .getTargetTypeName ()) //
141
- .addModifiers (Modifier .PUBLIC ) //
142
- .addAnnotation (Generated .class ) //
148
+ builder .addModifiers (Modifier .PUBLIC ) //
143
149
.addJavadoc ("AOT generated $L repository implementation for {@link $T}.\n " , moduleName ,
144
150
repositoryInformation .getRepositoryInterface ());
145
151
@@ -177,15 +183,31 @@ public AotBundle build() {
177
183
return new AotBundle (javaFile , metadata );
178
184
}
179
185
180
- private MethodSpec buildConstructor () {
186
+ public AotBundle build () {
187
+
188
+ ClassName className = ClassName
189
+ .bestGuess ((targetClassName != null ? targetClassName : intendedTargetClassName ()).getCanonicalName ());
190
+ return build (TypeSpec .classBuilder (className ).addAnnotation (Generated .class ));
191
+ }
181
192
182
- RepositoryConstructorBuilder constructorBuilder = new RepositoryConstructorBuilder (
183
- generationMetadata );
193
+ public TypeReference intendedTargetClassName () {
194
+ return TypeReference .of ("%s.%s" .formatted (packageName (), typeName ()));
195
+ }
184
196
185
- if (constructorCustomizer != null ) {
186
- constructorCustomizer .accept (constructorBuilder );
197
+ public @ Nullable TypeReference actualTargetClassName () {
198
+
199
+ if (targetClassName == null ) {
200
+ return null ;
187
201
}
202
+ return targetClassName ;
203
+ }
188
204
205
+ AotRepositoryBuilder withTargetClassName (@ Nullable TypeReference targetClassName ) {
206
+ this .targetClassName = targetClassName ;
207
+ return this ;
208
+ }
209
+
210
+ private MethodSpec buildConstructor () {
189
211
return constructorBuilder .buildConstructor ();
190
212
}
191
213
@@ -252,15 +274,11 @@ public AotRepositoryFragmentMetadata getGenerationMetadata() {
252
274
return generationMetadata ;
253
275
}
254
276
255
- private ClassName className () {
256
- return new ClassNameGenerator (ClassName .get (packageName (), typeName ())).generateClassName ("Aot" , null );
257
- }
258
-
259
- private String packageName () {
277
+ public String packageName () {
260
278
return repositoryInformation .getRepositoryInterface ().getPackageName ();
261
279
}
262
280
263
- private String typeName () {
281
+ public String typeName () {
264
282
return "%sImpl" .formatted (repositoryInformation .getRepositoryInterface ().getSimpleName ());
265
283
}
266
284
@@ -280,7 +298,6 @@ public ProjectionFactory getProjectionFactory() {
280
298
return projectionFactory ;
281
299
}
282
300
283
-
284
301
/**
285
302
* Customizer interface to customize the AOT repository fragment constructor through
286
303
* {@link AotRepositoryConstructorBuilder}.
0 commit comments