Class ReflectionBeanDefinition<T>

java.lang.Object
io.micronaut.context.AbstractInitializableBeanDefinition<T>
io.micronaut.reflection.ReflectionBeanDefinition<T>
Type Parameters:
T - The bean type
All Implemented Interfaces:
BeanContextConfigurable, EnvironmentConfigurable, RuntimeBeanDefinition<T>, AnnotationMetadata, AnnotationMetadataDelegate, AnnotationMetadataProvider, AnnotationSource, BeanInfo<T>, Named, Ordered, ArgumentCoercible<T>, BeanContextConditional, BeanDefinition<T>, BeanDefinitionReference<T>, BeanType<T>, DisposableBeanDefinition<T>, InitializingBeanDefinition<T>, InjectableBeanDefinition<T>, InstantiatableBeanDefinition<T>, QualifiedBeanType<T>

public final class ReflectionBeanDefinition<T> extends AbstractInitializableBeanDefinition<T> implements RuntimeBeanDefinition<T>, InitializingBeanDefinition<T>, DisposableBeanDefinition<T>
A BeanDefinition over a Class, with the injection points, the executable methods and the life cycle a generated definition would have, to register a type the annotation processors never saw with a bean context at runtime.

The definition is read from the class as the processors read it at compilation time:

  • the bean is instantiated by the static method annotated Creator the class declares, else by one of its accessible - non-private - constructors: the only one, else the one annotated @Inject, else the one annotated Creator, else the canonical constructor of a record, else the first public one. That is the selection ClassElement#getPrimaryConstructor() makes at compilation time, but for a record whose constructors carry no annotation: the processors take the first public one there, where this takes the canonical one, which is the one the components describe. An annotation counts through its stereotypes, so a meta-annotated @Creator counts;
  • the non-static, non-final fields annotated @Inject, Value or Property, and the ones declaring a qualifier without @Inject, are injected, the super classes' first;
  • the methods annotated @Inject and the setters annotated with a qualifier - Value is one - are injected, the methods annotated @PostConstruct and @PreDestroy are the life cycle methods;
  • the methods annotated Executable, and the public methods of a type annotated Executable, are the executable methods;
  • the scope, the qualifier, the order, the exposed types of @Bean(typed = ...) and the conditions come from the annotations of the class, unless the builder overrides them.

An inherited injection point is read as the bean type sees it: a member a generic super class declares over a variable that the bean type gives a value to - a T dep of a class Base<T> inherited by a class Impl extends Base<Book> - is injected as the value, a Book, which is what a generated definition of the bean type asks for.

Each injected argument is resolved as a generated definition resolves it: a bean by type and qualifier, a Collection, an array, a Stream, an Optional or a Map of beans, a BeanRegistration or a collection of them, a configuration Value or Property. The features that need the processors - @ConfigurationProperties binding, @EachProperty and @EachBean iteration, @Parameter arguments, AOP advice - are not available to a reflective definition.

Since:
5.2.0
Author:
Denis Stepanov