Spring DI

@Factory @Bean are equivalent to Spring DI @Configuration @Bean and Micronaut @Factory @Bean.

@Factory

Factory beans allow logic to be used when creating a bean. Often this logic is based on environment variables or system properties (e.g. programmatically create a bean based on AWS region).

We annotate a class with @Factory to tell us that it contains methods that create beans. The factory class can itself have dependencies.

@Bean

We annotate methods on the factory class that create a bean with @Bean. These methods can have dependencies and will execute in the appropriate order depending on the dependencies they require.

Spring DI Note

This is equivalent to Spring DI @Configuration @Bean.

Example

@Factory
class Configuration {

  private final StartConfig startConfig;

  /**
   * Factory can have dependencies.
   */
  @Inject
  Configuration(StartConfig startConfig) {
    this.startConfig = startConfig;
  }

  @Bean
  Pump buildPump() {
    // maybe read System properties or environment variables
    return new FastPump(...);
  }

  /**
   * Method with dependencies as method parameters.
   */
  @Bean
  CoffeeMaker buildBar(Pump pump, Grinder grinder) {
    // maybe read System properties or environment variables
    return new CoffeeMaker(...);
  }
}

@Bean initMethod & destroyMethod

With @Bean we can specify an initMethod which will be executed on startup like @PostConstruct. Similarly a destroyMethod which execute on shutdown like @PreDestroy.

Example

@Factory
class Configuration {
  ...
  @Bean(initMethod = "init", destroyMethod = "close")
  CoffeeMaker buildCoffeeMaker(Pump pump) {
    return new CoffeeMaker(pump);
  }
}

The CoffeeMaker has the appropriate methods that are executed as part of the lifecycle.

class CoffeeMaker {
  public void init() {
    // lifecycle executed on start/PostConstruct
  }
  public void close() {
    // lifecycle executed on shutdown/PreDestroy
  }
  ...
}

JSR 330 Provider interface

Note that using @Factory plus @Bean is an alternative to the standard JSR 330 javax.inject.Provider interface.

Generally the use of @Factory plus @Bean is expected as it is relatively more convenient than using javax.inject.Provider. In Spring DI terms the use of @Configuration @Bean is now arguably more common than Spring's FactoryBean interface.