Core dependency injection interfaces and components for the Micronaut Framework
—
Bean definitions contain compile-time metadata about beans including their type, dependencies, injection points, and lifecycle methods. The Micronaut framework uses this information to perform dependency injection at runtime without reflection.
Represents metadata about a bean including its type, dependencies, and injection points.
public interface BeanDefinition<T> extends BeanType<T> {
Class<T> getBeanType();
Optional<Class<?>> getDeclaringType();
List<Argument<?>> getConstructorArguments();
Collection<MethodInjectionPoint<T, ?>> getInjectedMethods();
Collection<FieldInjectionPoint<T, ?>> getInjectedFields();
Collection<ExecutableMethod<T, ?>> getExecutableMethods();
Optional<Method> getPostConstructMethod();
Optional<Method> getPreDestroyMethod();
boolean isAbstract();
boolean isSingleton();
boolean isConfigurationProperties();
T instantiate(BeanResolutionContext resolutionContext, BeanContext context);
T instantiate(BeanResolutionContext resolutionContext, BeanContext context, Object... args);
}Factory interface for creating bean instances.
public interface BeanFactory<T> {
T build(BeanResolutionContext resolutionContext, BeanContext context, BeanDefinition<T> definition);
T build(BeanResolutionContext resolutionContext, BeanContext context, BeanDefinition<T> definition, Object... args);
}Base interface for points where dependency injection occurs.
public interface InjectionPoint<T> {
BeanDefinition getDeclaringBean();
Argument<T> getArgument();
AnnotationMetadata getAnnotationMetadata();
}Injection point for method injection (setter injection, @PostConstruct methods).
public interface MethodInjectionPoint<B, T> extends InjectionPoint<T>, ExecutableMethod<B, T> {
T invoke(B instance, BeanResolutionContext resolutionContext, BeanContext context);
T invoke(B instance, BeanResolutionContext resolutionContext, BeanContext context, Object... args);
boolean requiresReflection();
}Injection point for field injection.
public interface FieldInjectionPoint<B, T> extends InjectionPoint<T> {
void set(B instance, BeanResolutionContext resolutionContext, BeanContext context);
T get(B instance);
String getName();
boolean requiresReflection();
}Context information during bean resolution and creation.
public interface BeanResolutionContext extends AutoCloseable {
BeanContext getContext();
BeanDefinition<?> getRootDefinition();
Path getPath();
<T> Optional<T> get(CharSequence name, Class<T> requiredType);
BeanResolutionContext copy();
void close();
}Represents the resolution path during bean creation.
public interface Path {
Optional<Path> getParent();
String toString();
Path.Segment getCurrentSegment();
interface Segment {
String getName();
BeanDefinition getDeclaringType();
Argument getArgument();
}
}Represents method/constructor arguments with type information.
public class Argument<T> implements AnnotatedElement {
public static <T> Argument<T> of(Class<T> type);
public static <T> Argument<T> of(Class<T> type, String name);
public static <T> Argument<T> of(Class<T> type, AnnotationMetadata annotationMetadata);
public Class<T> getType();
public String getName();
public Argument[] getTypeParameters();
public Map<String, Argument<?>> getTypeVariables();
public boolean isNullable();
public boolean isOptional();
}import io.micronaut.context.ApplicationContext;
import io.micronaut.inject.BeanDefinition;
public class BeanDefinitionExample {
public static void main(String[] args) {
try (ApplicationContext context = ApplicationContext.run()) {
// Get bean definition
BeanDefinition<UserService> definition =
context.getBeanDefinition(UserService.class);
// Examine bean metadata
System.out.println("Bean type: " + definition.getBeanType());
System.out.println("Is singleton: " + definition.isSingleton());
System.out.println("Constructor args: " + definition.getConstructorArguments());
// Create instance using definition
UserService service = definition.instantiate(
context.getBeanResolutionContext(),
context
);
}
}
}import io.micronaut.context.ApplicationContext;
import io.micronaut.inject.BeanDefinition;
import io.micronaut.inject.MethodInjectionPoint;
import io.micronaut.inject.FieldInjectionPoint;
public class InjectionPointExample {
public static void main(String[] args) {
try (ApplicationContext context = ApplicationContext.run()) {
BeanDefinition<OrderService> definition =
context.getBeanDefinition(OrderService.class);
// Inspect method injection points
Collection<MethodInjectionPoint<OrderService, ?>> methodInjections =
definition.getInjectedMethods();
for (MethodInjectionPoint<OrderService, ?> injection : methodInjections) {
System.out.println("Method: " + injection.getName());
System.out.println("Argument: " + injection.getArgument());
}
// Inspect field injection points
Collection<FieldInjectionPoint<OrderService, ?>> fieldInjections =
definition.getInjectedFields();
for (FieldInjectionPoint<OrderService, ?> injection : fieldInjections) {
System.out.println("Field: " + injection.getName());
System.out.println("Type: " + injection.getArgument().getType());
}
}
}
}import io.micronaut.context.ApplicationContext;
import io.micronaut.inject.BeanDefinition;
public class ManualCreationExample {
public static void main(String[] args) {
try (ApplicationContext context = ApplicationContext.run()) {
BeanDefinition<DatabaseService> definition =
context.getBeanDefinition(DatabaseService.class);
// Create with custom arguments
DatabaseService service = definition.instantiate(
context.getBeanResolutionContext(),
context,
"jdbc:postgresql://localhost/mydb", // connection string
"myuser", // username
"mypass" // password
);
service.connect();
}
}
}import io.micronaut.context.ApplicationContext;
import io.micronaut.inject.BeanDefinition;
import io.micronaut.context.Argument;
public class ArgumentExample {
public static void main(String[] args) {
try (ApplicationContext context = ApplicationContext.run()) {
BeanDefinition<PaymentService> definition =
context.getBeanDefinition(PaymentService.class);
// Examine constructor arguments
List<Argument<?>> constructorArgs = definition.getConstructorArguments();
for (Argument<?> arg : constructorArgs) {
System.out.println("Argument name: " + arg.getName());
System.out.println("Argument type: " + arg.getType());
System.out.println("Is nullable: " + arg.isNullable());
System.out.println("Is optional: " + arg.isOptional());
// Check for generic type parameters
Argument<?>[] typeParams = arg.getTypeParameters();
if (typeParams.length > 0) {
System.out.println("Generic parameters: " + Arrays.toString(typeParams));
}
}
}
}
}import io.micronaut.inject.BeanFactory;
import io.micronaut.inject.BeanDefinition;
import io.micronaut.context.BeanResolutionContext;
import io.micronaut.context.BeanContext;
import jakarta.inject.Singleton;
@Singleton
public class CustomServiceFactory implements BeanFactory<CustomService> {
@Override
public CustomService build(BeanResolutionContext resolutionContext,
BeanContext context,
BeanDefinition<CustomService> definition) {
// Custom bean creation logic
String environment = context.getEnvironment().getActiveNames().iterator().next();
if ("prod".equals(environment)) {
return new ProductionCustomService();
} else {
return new DevelopmentCustomService();
}
}
}import io.micronaut.context.ApplicationContext;
import io.micronaut.context.BeanResolutionContext;
import io.micronaut.inject.BeanDefinition;
public class ResolutionContextExample {
public static void main(String[] args) {
try (ApplicationContext context = ApplicationContext.run()) {
try (BeanResolutionContext resolutionContext = context.getBeanResolutionContext()) {
BeanDefinition<ComplexService> definition =
context.getBeanDefinition(ComplexService.class);
// Create bean with resolution context
ComplexService service = definition.instantiate(resolutionContext, context);
// Resolution context tracks the path
System.out.println("Resolution path: " + resolutionContext.getPath());
service.performComplexOperation();
}
}
}
}Base implementation class for bean definitions.
public abstract class AbstractBeanDefinition<T> implements BeanDefinition<T> {
protected AbstractBeanDefinition(Class<T> type,
MethodOrFieldReference constructor,
AnnotationMetadata annotationMetadata,
MethodReference[] methodInjection,
FieldReference[] fieldInjection,
ExecutableMethodsDefinition<T> executableMethodsDefinition,
Map<String, Argument<?>[]> typeArgumentsMap);
// Implements BeanDefinition interface methods
}Default implementation for field injection.
public class DefaultFieldInjectionPoint<B, T> implements FieldInjectionPoint<B, T> {
public DefaultFieldInjectionPoint(BeanDefinition declaringBean,
Class<T> fieldType,
String field,
AnnotationMetadata annotationMetadata,
Argument[] arguments);
// Implements FieldInjectionPoint interface methods
}import io.micronaut.context.Argument;
public class ArgumentCreationExample {
public static void main(String[] args) {
// Create basic argument
Argument<String> stringArg = Argument.of(String.class, "message");
// Create generic argument
Argument<List<String>> listArg = Argument.of(List.class, "items")
.withTypeParameters(Argument.of(String.class));
// Create optional argument
Argument<Optional<Integer>> optionalArg = Argument.of(Optional.class, "count")
.withTypeParameters(Argument.of(Integer.class));
System.out.println("String arg: " + stringArg);
System.out.println("List arg: " + listArg);
System.out.println("Optional arg: " + optionalArg);
}
}Install with Tessl CLI
npx tessl i tessl/maven-io-micronaut--micronaut-inject