为了账号安全,请及时绑定邮箱和手机立即绑定

Guice - 使用两种不同的实现注入对象

Guice - 使用两种不同的实现注入对象

慕虎7371278 2022-07-20 10:06:58
首先,我不得不说我尝试用谷歌搜索这个问题的答案,但没有答案能解释我的疑问。无论如何,我想了解的是以下内容:public interface Animal{ public void makeSound(int times);}这个接口有两种不同的实现:public class Cat implements Animal{ @Override public void makeSound(int times){   for(int=0;i<times;i++){       this.meow();   } }}public class Dog implements Animal{ @Override public void makeSound(int times){   for(int=0;i<times;i++){       this.wolf();   }  }}我将使用这些实现,如下例所示:public class AnimalStateManager { @Inject private Animal animal; public void makeAnimalAct(){   animal.makeSound(100) }}更新 1.1 到帖子我还有一门使用相同的“动物”界面的课程: public class AnimalMakeSoundOnce {     @Inject     private Animal animal;     public void makeSoundOnce(){       animal.makeSound(1)     }    }所以我的问题是: 1- 我怎么知道要注入 AnimalStateManager 的实现是什么?2- 如果我想将“AnimalStateManager”上的“动物”对象强制为猫怎么办?更新 1.1 到 帖子 3- 如果我想让 AnimalMakeSoundOnce 使用 Dog 实现而 AnimalStateManager 使用 Cat 实现怎么办?
查看完整描述

2 回答

?
暮色呼如

TA贡献1853条经验 获得超9个赞

在 Guice 中,您必须实现一个模块(覆盖AbstractModule类)并将 Animal 绑定到特定的实现类。要回答您的问题:


您当然可以调用animal.getClass()以在运行时检查注入了哪个实现类。但这会打破 IOC 的原则,即无论您使用哪种具体实现都无关紧要。


要强制animal您AnimalStateManager成为猫,您必须编写自己的模块。


public class AnimalStateModule extends AbstractModule {


    @Override

    protected void configure() {

        bind(Animal.class).to(Cat.class);

    }

}

并实例化 AnimalState:


Injector inj = Guice.createInjector(new AnimalStateModule());

final AnimalStateManager ass = inj.getInstance(AnimalStateManager.class);

ass.makeAnimalAct(); // will cause a call to Cat.meow()


查看完整回答
反对 回复 2022-07-20
?
慕的地8271018

TA贡献1796条经验 获得超4个赞

我认为另一个重要问题是您将如何同时使用 MakeSound 和 MakeSoundOnce 对象。在上面创建的同一模块中,有多种方法可以指定您想要的类型,这两种方法都是绑定注释的方法(https://github.com/google/guice/wiki/BindingAnnotations):


1)您可以使用Guice提供的@Named注解。您将拥有如下所示的内容:


@Override

protected void configure() {

    bind(Animal.class).annotatedWith(Names.named("Cat")).to(Cat.class);

    bind(Animal.class).annotatedWith(Names.named("Dog")).to(Dog.class);

}

然后将用于:


@Inject @Named("Cat") private Animal animal;

在您的 *MakeSound 课程中。


2)您还可以创建自己的注释(在上面的同一链接中进行了非常详细的描述),这将使您可以选择使用:


@Inject @Cat private Animal animal;

在您的 *MakeSound 课程中。大多数时候我们坚持使用@Named 注解,因为它不需要创建额外的注解接口。


*MakeSound 类会通过注入实现吗?并且您是否需要在您描述的 *MakeSound 类中切换 Dog/Cat 实现(即,希望猫只喵一次,反之亦然)?


查看完整回答
反对 回复 2022-07-20
  • 2 回答
  • 0 关注
  • 92 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信