Guice在不使用@Singleton的情况下将单个实例注入多个对象

cru*_*ush 4 java guice cyclic-dependency

我正在阅读Guice文档,并且遇到了一个标记为" 消除循环(推荐)"的部分,这一部分引起了我的兴趣,因为这正是导致我今天阅读文档的问题.

基本上,为了消除循环依赖关系,您可以"将依赖关系案例提取到一个单独的类中".好的,那里没什么新鲜的.

所以,在这个例子中,我们有.

public class Store {
        private final Boss boss;
        private final CustomerLine line;
        //...

        @Inject public Store(Boss boss, CustomerLine line) {
                this.boss = boss; 
                this.line = line;
                //...
        }

        public void incomingCustomer(Customer customer) { line.add(customer); } 
}

public class Boss {
        private final Clerk clerk;
        @Inject public Boss(Clerk clerk) {
                this.clerk = clerk;
        }
}

public class Clerk {
        private final CustomerLine line;

        @Inject Clerk(CustomerLine line) {
                this.line = line;
        }

        void doSale() {
                Customer sucker = line.getNextCustomer();
                //...
        }
}
Run Code Online (Sandbox Code Playgroud)

你有一个Store和一个Clerk,每个需要有一个单个实例的引用CustomerLine.这个概念没有问题,并且很容易使用经典的依赖注入:

CustomerLine customerLine = new CustomerLine();
Clerk clerk = new Clerk(customerLine);
Boss boss = new Boss(clerk);
Store store = new Store(boss, customerLine);
Run Code Online (Sandbox Code Playgroud)

这很容易,但是现在,我需要使用Guice注射器来做到这一点.因此,我的问题是实施以下内容:

您可能希望确保Store和Clerk都使用相同的CustomerLine实例.

是的,这正是我想要做的.但是我如何在Guice模块中做到这一点?

public class MyModule extends AbstractModule implements Module {
    @Override
    protected void configure() {
        //Side Question: Do I need to do this if there if Boss.class is the implementation?
        bind(Boss.class);
        bind(CustomerLine.class).to(DefaultCustomerLine.class); //impl
    }
}
Run Code Online (Sandbox Code Playgroud)

我用我的模块创建了一个注入器:

Injector injector = Guice.createInjector(new MyModule());
Run Code Online (Sandbox Code Playgroud)

现在,我想要一个实例Store:

Store store = injector.getInstance(Store.class);
Run Code Online (Sandbox Code Playgroud)

这将注入的新实例CustomerLine,并Boss进入该实例Store.Boss然而,获取一个实例Clerk也会注入一个实例CustomerLine.此时,它将是一个新实例,从注入的实例中唯一Store.

问题重新审视

  • 如何能StoreClerk共享相同的实例在这个序列中,不使用@Singleton

如果需要更多信息,请告诉我,或者这个问题没有说清楚,我一定会修改.

Niz*_*ziL 11

您应该使用提供商

public class StoreProvider implements Provider<Store> {
  @Inject 
  private Boss boss ;

  public Store get() {
    return new Store(boss, boss.getClerk().getCustomerLine());
  }
}
Run Code Online (Sandbox Code Playgroud)

然后将其绑定在您的模块中

bind(Store.class).toProvider(StoreProvider.class);