You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit focuses on improving the AOT section on programmatic
registration of additional beans. This makes it more clear that a
`BeanDefinitionRegistry` must be used and that singletons are not
processed.
Closesgh-32240Closesgh-32241
Copy file name to clipboardExpand all lines: framework-docs/modules/ROOT/pages/core/aot.adoc
+34-4Lines changed: 34 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -17,8 +17,11 @@ Applying such optimizations early implies the following restrictions:
17
17
* The beans defined in your application cannot change at runtime, meaning:
18
18
** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.
19
19
** `Environment` properties that impact the presence of a bean (`@Conditional`) are only considered at build time.
20
-
* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time (see related {spring-framework-issues}/29555[spring-framework#29555] issue).
21
-
* Make sure that the bean type is as precise as possible.
20
+
* Bean definitions with instance suppliers (lambdas or method references) cannot be transformed ahead-of-time
21
+
* Beans registered as singletons (using `registerSingleton`, typically from
22
+
`ConfigurableListableBeanFactory`) cannot be transformed ahead-of-time either.
23
+
* As we can't rely on the instance, make sure that the bean type is as precise as
24
+
possible.
22
25
23
26
TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.
24
27
@@ -35,7 +38,7 @@ We intend to support more JVM-based use cases in future generations.
35
38
[[aot.basics]]
36
39
== AOT engine overview
37
40
38
-
The entry point of the AOT engine for processing an `ApplicationContext` arrangement is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:
41
+
The entry point of the AOT engine for processing an `ApplicationContext` is `ApplicationContextAotGenerator`. It takes care of the following steps, based on a `GenericApplicationContext` that represents the application to optimize and a {spring-framework-api}/aot/generate/GenerationContext.html[`GenerationContext`]:
39
42
40
43
* Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.
41
44
* Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.
In this mode, xref:core/beans/factory-extension.adoc#beans-factory-extension-factory-postprocessors[`BeanFactoryPostProcessor` implementations] are invoked as usual.
68
71
This includes configuration class parsing, import selectors, classpath scanning, etc.
69
72
Such steps make sure that the `BeanRegistry` contains the relevant bean definitions for the application.
70
-
If bean definitions are guarded by conditions (such as `@Profile`), these are discarded at this stage.
73
+
If bean definitions are guarded by conditions (such as `@Profile`), these are evaluated
74
+
and bean definitions that don't match their conditions are discarded at this stage.
75
+
76
+
If custom code needs to register extra beans programmatically, make sure that they use
77
+
`BeanDefinitionRegistry`, and not `BeanFactory` as only bean definitions are taken into
78
+
account. A good pattern is to implement `ImportBeanDefinitionRegistrar` and register it
79
+
via an `@Import` on one of your configuration classes.
71
80
72
81
Because this mode does not actually create bean instances, `BeanPostProcessor` implementations are not invoked, except for specific variants that are relevant for AOT processing.
73
82
These are:
@@ -207,6 +216,27 @@ However, keep in mind that some optimizations are made at build time based on a
207
216
208
217
This section lists the best practices that make sure your application is ready for AOT.
209
218
219
+
[[aot.bestpractices.bean-registration]]
220
+
== Programmatic bean registration
221
+
The AOT engine takes care of the `@Configuration` model, and any callback that might be
222
+
invoked as part of processing your configuration. If you need to register additional
223
+
beans programmatically, make sure to use a `BeanDefinitionRegistry` to register
224
+
bean definitions.
225
+
226
+
This can be typically done via a `BeanDefinitionRegistryPostProcessor`. Note that, if it
227
+
is registered itself as a bean, it will be invoked again at runtime unless you make
228
+
sure to implement `BeanFactoryInitializationAotProcessor` as well. A more idiomatic
229
+
way is to implement `ImportBeanDefinitionRegistrar` and register it using `@Import` on
230
+
one of your configuration classes. This invokes your custom code as part of configuration
231
+
class parsing.
232
+
233
+
If you declare additional beans programmatically using a different callback, there are
234
+
likely not going to be handled by the AOT engine, and therefore no hints are going to be
235
+
generated for them. Depending on the environment, those beans may not be registered at
236
+
all. For instance, classpath scanning does not work in a native image as there is no
237
+
notion of classpath. For cases like this, it is crucial that the scanning happens at
0 commit comments