使用 Guice 时,是否可以获取绑定在模块中的对象?

When using Guice, is it possible to get an object that was bound in a module?

public class MyModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(Helper.class).toProvider(HelperProvider.class);
        ServiceInterceptor serviceInterceptor = new ServiceInterceptor(manager);
        bindInterceptor(annotatedWith(With.class), annotatedWith(ServiceName.class), serviceInterceptor);
    }

    @Provides
    @Singleton
    public Manager manager(final Helper helper) {
       Manager manager = new DefaultManager(helper);
       return manager;
    }
}

基本上,我的问题是我需要管理器实例来创建serviceInterceptor 实例,并且我需要bindInterceptor 中的serviceInterceptor。我是 Guice 的新手,所以我觉得这很简单,我找不到解决方法...

这可以通过为您的对象实例请求注入来解决。考虑我写的这个例子:

public class TestModule2 extends AbstractModule {

    @Override
    protected void configure() {
        bind(Helper.class).in(Singleton.class);
        bind(Manager.class).to(ManagerImpl.class).in(Singleton.class);

        MyInterceptor i = new MyInterceptor();
        requestInjection(i); // intercept the thing

        bindInterceptor(Matchers.any(), Matchers.any(), i);
    }

    public static interface Manager {
        public void talk();
    }

    public static class ManagerImpl implements Manager {

        @Inject
        public ManagerImpl(Helper h) {
        }

        @Override
        public void talk() {
            System.out.println("talking");
        }
    }

    public static class Helper {

    }

    public static class MyInterceptor implements MethodInterceptor {

        @Inject
        private Manager m;

        public MyInterceptor() {
        }

        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            System.out.println("intercept and manager " + m.getClass().getName());
            return invocation.proceed();
        }
    }

    public static void main(String[] args) {
        Injector createInjector = Guice.createInjector(new TestModule2());
        Manager instance = createInjector.getInstance(Manager.class);
        instance.talk();
    }
}

解释一下:

  1. 我首先以正常方式绑定所有实例。这将是助手和经理。 Manager可以注入helper等等。不要忘记注入注释。

  2. 我创建了我的拦截器方法。现在我需要注射这个。 Guice 有一个适用于该场景的方法:

    MyInterceptor i = new MyInterceptor();
    requestInjection(i); // inject the thing
    

这现在将管理器实例放入您的拦截器中。

最后,当我 运行 上面的代码时,我得到:

intercept and manager test.guice.TestModule2$ManagerImpl$$EnhancerByGuice$$e5e270bc
talking

请注意,拦截器正在打印其消息,然后执行方法调用。

希望对您有所帮助,

阿图尔