Guice:使用@Named创建对象

2022-09-03 03:59:23

使用 Guice,如果我有

@Inject @Named("light")
Color light;

我可以使用

bind(Color.class).annotatedWith(Names.named("light"))
    .toInstance(new Color("white"));

以将其绑定到白色(如果颜色构造函数只需要颜色名称)。

但是,如果Color构造函数还需要由Guice创建的对象,我该怎么办呢?例如:

@Inject
public Color(ColorSet colorset, String colorName) {...}

其中颜色集由 Guice 在运行时创建,在 configure(){...} 中不可用。

我想在没有:

  • 为我需要注入的每种颜色创建一个类/子类(如WhiteColor)
  • 在我的代码中直接使用反射
  • 更改我的类以使用而不是ColorFactoy factory; factory.get("light");@Named("light") Color light;

答案 1

最好的方法不是用工厂,而是用@Provides方法。我的公司非常非常广泛地使用 Guice,并且总是被认为是一个坏主意,因为它可以很容易地设置一个非常脆弱的隐式依赖关系图。requestInjection

它应该是什么样子的:

public class FooModule extends AbstractModule {
  protected void configure() {
    // do configuration
  }

  @Provides
  @Named("white")
  Color provideWhiteColor(ColorSet colorSet) {
    return colorSet.white(); // or whatever
  }

  @Provides
  @Named("black")
  Color provideBlackColor(ColorSet colorSet) {
    return colorSet.black(); // or whatever
  }

  // etc
}

答案 2

您可以在模块中设置一个工厂,并请求在其上注入以填充ColorSet。

模块:

ColorFactory colorFactory = new ColorFactory();

requestInjection(colorFactory);

bind(Color.class).annotatedWith(Names.named("light")).toInstance(colorFactory.buildColor("white"));
bind(Color.class).annotatedWith(Names.named("dark")).toInstance(colorFactory.buildColor("black"));

颜色工厂:

public class ColorFactory {

    private ColorSet colorSet;

    public Color buildColor(String color){
        return new Color(colorSet, color);
    }

    @Inject
    public void setColorSet(ColorSet colorSet) {
        this.colorSet = colorSet;
    }
}

推荐