有条件地实例化使用 @Inject 的 类

Conditionally instantiating classes that use @Inject

我正在尝试了解如何处理有条件地创建使用 @Inject 的 class 的新实例。在下面的示例中,我有一个基于参数实例化 classes 的工厂。

AnimalFactory 无法访问我的应用程序的 injector 主 class,所以我无法使用 injector.getInstance(Cat.class)

class AnimalFactory {

    public IAnimal create(AnimalType type) {
        if (type.equals(AnimalType.CAT)) {
            return new Cat(); // Cat uses @Inject, so this won't work of course. But ???
        } else if (type.equals(AnimalType.DOG)) {
            return new Dog(); 
        }
    }
}

在我的应用程序的其余部分,classes 被注入到我的构造函数中,因为我总是需要它们。 Guice 为每个创建一个 instance/singleton。但在这种情况下,我 不想 为每只动物创建和注入实例,因为除了一个之外,其他都需要。

您可以按照说明使用 MapBinder here:

public class AnimalModule extends AbstractModule {
  public void configure() {
    MapBinder<AnimalType, IAnimal> animalBinder= MapBinder.newMapBinder(binder(), AnimalType.class, IAnimal.class);

    animalBinder.addBinding(AnimalType.DOG).to(Dog.class);
     ...
  }
}

然后在您的工厂中使用它:

class AnimalFactory {
   @Inject
   Map<AnimalType, IAnimal> animals;

   public IAnimal create(AnimalType type) {
       return animals.get(type);
   }
 }

实际上我处理过完全相同的问题,并且我编写了一个允许您创建 self-populating 工厂的功能。这意味着如果您在 Spring/Spring-boot 环境中工作,您可以创建一个工厂,该工厂可以访问和提供任何实现由 Spring-boot 管理的 class 的接口,而无需在工厂中注入。您还可以为实例提供自定义名称。所以,它似乎完全适合你的情况。这是一篇非常详细地描述该功能的文章的link:Non-intrusive access to "Orphaned" Beans in Spring framework. Also, in MgntUtils library Javadoc there is a good description of the feature here enter link description here. The library itself including source code could be found on Github here and in the package com.mgnt.lifecycle.management.example there is a working example. Maven artifacts are here