Skip to content

Commit c46d628

Browse files
committed
Review AOT recommendations in the reference guide
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. Closes gh-32240 Closes gh-32241
1 parent 750cb73 commit c46d628

File tree

1 file changed

+34
-4
lines changed
  • framework-docs/modules/ROOT/pages/core

1 file changed

+34
-4
lines changed

framework-docs/modules/ROOT/pages/core/aot.adoc

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,11 @@ Applying such optimizations early implies the following restrictions:
1717
* The beans defined in your application cannot change at runtime, meaning:
1818
** `@Profile`, in particular profile-specific configuration needs to be chosen at build time.
1919
** `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.
2225

2326
TIP: See also the xref:core/aot.adoc#aot.bestpractices[] section.
2427

@@ -35,7 +38,7 @@ We intend to support more JVM-based use cases in future generations.
3538
[[aot.basics]]
3639
== AOT engine overview
3740

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`]:
3942

4043
* Refresh an `ApplicationContext` for AOT processing. Contrary to a traditional refresh, this version only creates bean definitions, not bean instances.
4144
* Invoke the available `BeanFactoryInitializationAotProcessor` implementations and apply their contributions against the `GenerationContext`.
@@ -67,7 +70,13 @@ include-code::./AotProcessingSample[tag=aotcontext]
6770
In this mode, xref:core/beans/factory-extension.adoc#beans-factory-extension-factory-postprocessors[`BeanFactoryPostProcessor` implementations] are invoked as usual.
6871
This includes configuration class parsing, import selectors, classpath scanning, etc.
6972
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.
7180

7281
Because this mode does not actually create bean instances, `BeanPostProcessor` implementations are not invoked, except for specific variants that are relevant for AOT processing.
7382
These are:
@@ -207,6 +216,27 @@ However, keep in mind that some optimizations are made at build time based on a
207216

208217
This section lists the best practices that make sure your application is ready for AOT.
209218

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
238+
build time.
239+
210240
[[aot.bestpractices.bean-type]]
211241
=== Expose The Most Precise Bean Type
212242

0 commit comments

Comments
 (0)