【问题标题】:Java Guice ProviderJava Guice 提供程序
【发布时间】:2015-10-28 02:02:29
【问题描述】:

我有一个小问题,我想不通来挽救我的生命。

基本上我需要随时使用 guice 动态注册类,然后循环遍历它们。

假设这是我注册策略的课程,但这些策略可以随时通过应用程序运行添加。

// Strategy registration may happen anytime, this is just an example
strategyManager.register(ExampleStrategy1.class);
strategyManager.register(ExampleStrategy2.class);

StrategyImpl 类

public class StrategyImpl implements Strategy {

    @Override
    public void register(Class<? extends StrategyDispatcher> strat) {
        //Add this class into provider or create an instance for it and add it into guice but how?
    }

    @Override
    public void dispatchStrategy() {
        //Find all strategies and execute them
    }

}

我尝试使用提供程序,但不知道如何将注册的类添加到提供程序中并全部检索它们?

@Override
protected void configure() {
    bind(Strategy.class).toProvider(StrategyProvider.class);
}

我的提供者类总是得到相同的实例

public class StrategyProvider implements Provider<StrategyDispatcher> {

    public LogManager get() {
        return new StrategyDispatcherImpl();
    }

}

我添加的策略扩展了 StrategyDispatcherImpl 类以便我可以转换它们?

我需要将多个绑定添加到同一个实例,但它需要动态完成,而不是使用配置中的绑定方法,而是通过另一种方式找到所有这些策略并执行它们。

【问题讨论】:

  • 你可能想尝试的另一件事是 hk2 (hk2.java.net),它专门设计为动态的,允许随时添加和删除服务,而不仅仅是在初始化时

标签: java guice


【解决方案1】:

如果您真的需要它在应用程序生命周期中的“任何时间”发生,那么 Guice 那么我认为您将需要某种 Guice-aware Factory。即

public class TestStuff {
    @Test
    public void testDynamicCreation() {
        Injector injector = Guice.createInjector();
        StrategyManager manager  = injector.getInstance(StrategyManager.class);
        Hello hello = injector.getInstance(Hello.class);
        manager.doStuff();
        assertThat(hello.helloCalled, is(false));

        manager.register(Hello.class); // DYNAMIC!!
        manager.doStuff();
        assertThat(hello.helloCalled, is(true));
    }
}

interface Strategy {
    void doStuff();
}

@Singleton
class Hello implements Strategy {
    boolean helloCalled = false;
    public void doStuff() {
        helloCalled = true;
    }
}


class StrategyManager {
    private final Collection<Strategy> strategies = new ArrayList<>();
    private final StrategyFactory factory;

    @Inject
    StrategyManager(StrategyFactory factory) {
        this.factory = factory;
    }

    public void register(Class<? extends Strategy> strat) {
        strategies.add(factory.create(strat));
    }

    public void doStuff() {
        for (Strategy s : strategies) {
            s.doStuff();
        }
    }
}

class StrategyFactory {
    private final Injector injector;

    @Inject
    StrategyFactory(Injector injector) {
        this.injector = injector;
    }

    public Strategy create(Class<? extends Strategy> clazz) {
        return injector.getInstance(clazz);
    }
}

如果在初始化阶段之后它不是“动态的”,那么我认为你是在“multibinder”之后。

【讨论】:

  • 您好,您能告诉我您注册课程的方法吗? manager.register(Hello.class); // 动态的!! manager.doStuff();
  • manager.register(Hello.class); 是它注册类的方式。你用你想注册的类来调用它。
猜你喜欢
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
  • 2016-07-26
  • 2019-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多