3.4 Injectable Container Types

In addition to being able to inject beans Micronaut natively supports injecting the following types:

Table 1. Injectable Container Types
TypeDescriptionExample

java.util.Optional

An Optional of a bean. If the bean doesn’t exist empty() is injected

Optional<Engine>

java.lang.Iterable

An Iterable or subtype of Iterable (example List, Collection etc.)

Iterable<Engine>

java.util.stream.Stream

A lazy Stream of beans

Stream<Engine>

Array

A native array of beans of a given type

Engine[]

Provider

A javax.inject.Provider if a circular dependency requires it or to instantiate a prototype for each get call.

Provider<Engine>

A prototype bean will have one instance created per place the bean is injected. When a prototype bean is injected as a Provider, each call to get() will create a new instance.

Collection Ordering

When injecting a collection of beans, they will not be ordered by default. To allow for the beans to be ordered, implement the Ordered interface. If the requested bean type does not implement Ordered, then the @Order annotation will be searched for on any beans.

The @Order annotation is especially useful for ordering beans created by factories where the bean type is a class in a third party library. In this example, both LowRateLimit and HighRateLimit implement the RateLimit interface.

Factory with @Order

  1. import io.micronaut.context.annotation.Factory;
  2. import io.micronaut.core.annotation.Order;
  3. import javax.inject.Singleton;
  4. import java.time.Duration;
  5. @Factory
  6. public class RateLimitsFactory {
  7. @Singleton
  8. @Order(20)
  9. LowRateLimit rateLimit2() {
  10. return new LowRateLimit(Duration.ofMinutes(50), 100);
  11. }
  12. @Singleton
  13. @Order(10)
  14. HighRateLimit rateLimit1() {
  15. return new HighRateLimit(Duration.ofMinutes(50), 1000);
  16. }
  17. }

Factory with @Order

  1. import io.micronaut.context.annotation.Factory
  2. import io.micronaut.core.annotation.Order
  3. import javax.inject.Singleton
  4. import java.time.Duration
  5. @Factory
  6. class RateLimitsFactory {
  7. @Singleton
  8. @Order(20)
  9. LowRateLimit rateLimit2() {
  10. new LowRateLimit(Duration.ofMinutes(50), 100);
  11. }
  12. @Singleton
  13. @Order(10)
  14. HighRateLimit rateLimit1() {
  15. new HighRateLimit(Duration.ofMinutes(50), 1000);
  16. }
  17. }

Factory with @Order

  1. import io.micronaut.context.annotation.Factory
  2. import io.micronaut.core.annotation.Order
  3. import java.time.Duration
  4. import javax.inject.Singleton
  5. @Factory
  6. class RateLimitsFactory {
  7. @Singleton
  8. @Order(20)
  9. fun rateLimit2(): LowRateLimit {
  10. return LowRateLimit(Duration.ofMinutes(50), 100)
  11. }
  12. @Singleton
  13. @Order(10)
  14. fun rateLimit1(): HighRateLimit {
  15. return HighRateLimit(Duration.ofMinutes(50), 1000)
  16. }
  17. }

When a collection of RateLimit beans are requested from the context, they will be returned in ascending order based on the value supplied in the annotation.