Skip to content

Commit 5421a36

Browse files
committed
Add section on runtime hints
See gh-29350
1 parent 3573022 commit 5421a36

File tree

1 file changed

+88
-2
lines changed

1 file changed

+88
-2
lines changed

framework-docs/src/docs/asciidoc/core/core-aot.adoc

Lines changed: 88 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ Each implementation can return an AOT contribution, based on the state of the be
9393
An AOT contribution is a component that contributes generated code that reproduce a particular behavior.
9494
It can also contribute `RuntimeHints` to indicate the need for reflection, resource loading, serialization, or JDK proxy.
9595

96-
`BeanFactoryInitializationAotProcessor` implementation should be registered in `META-INF/aot/spring.factories` with a key matching the fully qualified name of the interface.
96+
`BeanFactoryInitializationAotProcessor` implementation should be registered in `META-INF/spring/aot.factories` with a key equals to the fully qualified name of the interface.
9797

9898
It can also be implemented on a bean directly.
9999
In this mode, the bean provides an AOT contribution equivalent to the feature it provides with a regular runtime.
@@ -116,7 +116,7 @@ This interface is used as follows:
116116

117117
* On a `BeanPostProcessor` bean, to replace its runtime behavior.
118118
For instance <<beans-factory-extension-bpp-examples-aabpp,`AutowiredAnnotationBeanPostProcessor`>> is implementing this interface to generate code that injects members annotated with `@Autowired`.
119-
* On a type registered in `META-INF/aot/spring.factories` with a key matching the fully qualified name of the interface.
119+
* On a type registered in `META-INF/spring/aot.factories` with a key equals to the fully qualified name of the interface.
120120
Typically used whe the bean definition needs to be tuned for specific features of the core framework.
121121

122122
[NOTE]
@@ -189,3 +189,89 @@ The generated code above create equivalent bean definitions to the `@Configurati
189189
There is a bean definition for "`dataSourceConfiguration`" bean and one for "`dataSourceBean`".
190190
When a `datasource` instance is required, a `BeanInstanceSupplier` is called.
191191
This supplier invokes the `dataSource()` method on the `dataSourceConfiguration` bean.
192+
193+
194+
[[aot-hints]]
195+
== Runtime Hints
196+
Running an application as a native image requires additional information compared to a regular JVM runtime.
197+
For instance, GraalVM needs to know ahead of time if a component uses reflection.
198+
Similarly, classpath resources are not shipped in a native image unless specified explicitly.
199+
If the application needs to load a resource, it needs to be referenced.
200+
201+
The {api-spring-framework}/aot/hint/RuntimeHints.html[`RuntimeHints`] API collects the need for reflection, resource loading, serialization, and JDK proxy at runtime.
202+
The following example makes sure that `config/app.properties` can be loaded from the classpath at runtime:
203+
204+
[source,java,indent=0]
205+
----
206+
runtimeHints.resources().registerPattern("config/app.properties");
207+
----
208+
209+
A number of contracts are handled automatically during AOT processing.
210+
For instance, the return type of a `@Controller` method is inspected, and relevant reflection hints are added if we detect that the type should be serialized (typically to JSON).
211+
212+
For the cases that the core container cannot infer, you can register such hints programmatically.
213+
A number of convenient annotations are also provided for common use cases.
214+
215+
216+
[[aot-hints-import-runtime-hints]]
217+
=== `@ImportRuntimeHints`
218+
`RuntimeHintsRegistrar` implementations allow you to get a callback to the `RuntimeHints` instance managed by the AOT engine.
219+
Implementations of this interface can be registered using `@ImportRuntimeHints` on any Spring bean, or on a `@Bean` factory method.
220+
`RuntimeHintsRegistrar` implementations are detected and invoked at build-time.
221+
222+
[source,java,indent=0]
223+
----
224+
@Component
225+
@ImportRuntimeHints(MyComponentRuntimeHints.class)
226+
public class MyComponent {
227+
228+
229+
private static class MyComponentRuntimeHints implements RuntimeHintsRegistrar {
230+
231+
@Override
232+
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
233+
234+
}
235+
236+
}
237+
}
238+
----
239+
240+
If at all possible, `@ImportRuntimeHints` should be used as close as possible to the component that requires the hints.
241+
This way, if the component is not contributed to the `BeanFactory`, the hints won't either.
242+
243+
It is also possible to register an implementation statically by adding an entry in `META-INF/spring/aot.factories` with a key equals to the fully qualified name of the `RuntimeHintsRegistrar` interface.
244+
245+
246+
[[aot-hints-reflective]]
247+
=== `@Reflective`
248+
{api-spring-framework}/aot/hint/annotation/Reflective.html[`@Reflective`] provides an idiomatic way to flag the need for reflection on an annotated element.
249+
For instance, `@EventListener` is meta annotated with `@Reflective` as the underlying implementation invokes the annotated method using reflection.
250+
251+
By default, only Spring beans are considered and an invocation hint is added on the annotated element.
252+
This can be tuned by specifying a different `ReflectiveProcessor` implementation.
253+
254+
Library authors can reuse this annotation for their own use.
255+
If non-Spring beans need to be processed, a `BeanFactoryInitializationAotProcessor` can detect the relevant types and use `ReflectiveRuntimeHintsRegistrar` to process them.
256+
257+
258+
[[aot-hints-register-reflecting-for-binding]]
259+
=== `@RegisterReflectionForBinding`
260+
{api-spring-framework}/aot/hint/annotation/RegisterReflectionForBinding.html[`@RegisterReflectionForBinding`] is a specialization of `@Reflective` to register the need for serializing arbitrary types.
261+
A typical use case is the use of DTOs that the container cannot infer, such as using a web client within a method body.
262+
263+
`@RegisterReflectionForBinding` can be added on any Spring bean at class-level, but can also be specified on a method, field, or constructor to better indicate where the hints are actually required.
264+
The following example registers `Account` for serialization.
265+
266+
[source,java,indent=0]
267+
----
268+
@Component
269+
public class OrderService {
270+
271+
@RegisterReflectionForBinding(Account.class)
272+
public void process(Order order) {
273+
...
274+
}
275+
276+
}
277+
----

0 commit comments

Comments
 (0)