阅读(1964) (0)

Micronaut 可注射容器类型

2023-02-23 10:51:34 更新

除了能够注入 bean 之外,Micronaut 原生支持注入以下类型:

表 1. 可注射容器类型
类型 描述 示例

java.util.Optional

bean 的 Optional。如果 bean 不存在,则注入 empty()

Optional<Engine>

java.lang.Collection

集合或集合的子类型(例如列表、集合等)

Collection<Engine>

java.util.stream.Stream

A lazy Stream of beans

Stream<Engine>

Array

给定类型的原生 bean 数组

Engine[]

Provider

一个 javax.inject.Provider 如果循环依赖需要它,或者为每个 get 调用实例化一个原型。

Provider<Engine>

Provider

一个 jakarta.inject.Provider 如果循环依赖需要它或者为每个 get 调用实例化一个原型。

Provider<Engine>

BeanProvider

一个 io.micronaut.context.BeanProvider(如果循环依赖需要它或为每个 get 调用实例化一个原型)。

BeanProvider<Engine>

支持 3 种不同的提供程序类型,但是 BeanProvider 是我们建议使用的一种。

当将 java.lang.Collection 或 java.util.stream.Stream,bean 数组注入到与注入类型匹配的 bean 中时,拥有的 bean 将不是注入集合的成员。证明这一点的常见模式是聚合。例如:

@Singleton
class AggregateEngine implements Engine {
  @Inject
  List<Engine> engines;

  @Override
  public void start() {
    engines.forEach(Engine::start);
  }

  ...
}

在此示例中,注入的成员变量 engines 将不包含 AggregateEngine 的实例

一个原型 bean 将在每个注入 bean 的地方创建一个实例。当原型 bean 作为提供者注入时,每次调用 get() 都会创建一个新实例。

Collection Ordering

注入一组 bean 时,默认情况下它们是不排序的。实现 Ordered 接口以注入有序集合。如果请求的 bean 类型没有实现 Ordered,Micronaut 会在 bean 上搜索 @Order 注释。

@Order 注释对于订购由工厂创建的 bean 特别有用,其中 bean 类型是第三方库中的类。在这个例子中,LowRateLimit 和 HighRateLimit 都实现了 RateLimit 接口。

带有@Order 的工厂

 Java Groovy  Kotlin 
import io.micronaut.context.annotation.Factory;
import io.micronaut.core.annotation.Order;

import jakarta.inject.Singleton;
import java.time.Duration;

@Factory
public class RateLimitsFactory {

    @Singleton
    @Order(20)
    LowRateLimit rateLimit2() {
        return new LowRateLimit(Duration.ofMinutes(50), 100);
    }

    @Singleton
    @Order(10)
    HighRateLimit rateLimit1() {
        return new HighRateLimit(Duration.ofMinutes(50), 1000);
    }
}
import io.micronaut.context.annotation.Factory
import io.micronaut.core.annotation.Order

import jakarta.inject.Singleton
import java.time.Duration

@Factory
class RateLimitsFactory {

    @Singleton
    @Order(20)
    LowRateLimit rateLimit2() {
        new LowRateLimit(Duration.ofMinutes(50), 100);
    }

    @Singleton
    @Order(10)
    HighRateLimit rateLimit1() {
        new HighRateLimit(Duration.ofMinutes(50), 1000);
    }
}
import io.micronaut.context.annotation.Factory
import io.micronaut.core.annotation.Order
import java.time.Duration
import jakarta.inject.Singleton

@Factory
class RateLimitsFactory {

    @Singleton
    @Order(20)
    fun rateLimit2(): LowRateLimit {
        return LowRateLimit(Duration.ofMinutes(50), 100)
    }

    @Singleton
    @Order(10)
    fun rateLimit1(): HighRateLimit {
        return HighRateLimit(Duration.ofMinutes(50), 1000)
    }
}

当从上下文中请求一组 RateLimit bean 时,它们将根据注释中的值按升序返回。

按顺序注入 Bean

当注入单个 bean 实例时,@Order 注释也可用于定义哪个 bean 具有最高优先级,因此应该被注入。

选择单个实例时不考虑 Ordered 接口,因为这需要实例化 bean 来解析订单。