Guice TypeListener没有通知注入的类类型

我有以下Guice模块:

class MyModule extends AbstractModule {

    @Override
    protected void configure() {
        bindListener(Matchers.any(), new TypeListener() {...});    
    }

    @Provides
    SomeClass createSomeClass(final Parameter param) {
        log(param.getValue()); <-- this gets logged
        ...
    }
}

我发现奇怪的是,我的TypeListener没有得到有关Parameter类型的通知。 即使提供者被调用并返回SomeClass 。 我也很清楚地看到日志声明的Parameter是由Guice注入的。

@Override
protected void configure() {
    bind(Parameter.class);
    bindListener(Matchers.any(), new TypeListener() {...});    
}

我知道Untargetted绑定和声明:

一个非目标绑定通知注入器一个类型,所以它可能会热切地准备依赖关系。

我仍然期望Guice为任何明确绑定或首次注入的类型调用TypeListener

那么,我是否需要根据经验规则为这样的类创建非定向绑定?

注意:使用@Inject标记Parameter构造函数不能解决问题。

编辑:

完整的例子(希望我不要留下太多垃圾)如下:

public class TestGuice {

    public static void main(String[] args) {
        Injector parentInjector = Guice.createInjector(new ParentModule());
        Injector childInjector = parentInjector.createChildInjector(new SubModule());

        childInjector.getInstance(Runnable.class).run();
    }

    static class ParentModule extends AbstractModule {

        @Override
        protected void configure() {

        }
    }

    static class SubModule extends  AbstractModule {

        @Override
        protected void configure() {
            bind(SampleInjectedClass.class); // <-- Comment/uncomment here

            final TypeListener typeListener = new TypeListener() {
                public <I> void hear(TypeLiteral<I> type, TypeEncounter<I> encounter) {
                    System.out.println("Type: " + type.getRawType());
                }
            };

            bindListener(Matchers.any(), typeListener);
        }

        @Provides
        Runnable createRunnable(final SampleInjectedClass sampleClass) {
            return new Runnable() {

                @Override
                public void run() {
                    sampleClass.test();
                }
            };
        }
    }

    static class SampleInjectedClass {
        public void test() {
            System.out.println("Test");
        }
    }
}

如果该行存在,则输出为:

类型:class com.barcap.test.TestGuice $ SampleInjectedClass

键入:com.google.inject.internal.ProviderMethod类

测试

如果我删除我得到的行:

键入:com.google.inject.internal.ProviderMethod类

测试

我注意到,如果注入器不是通过createChildInjector代码创建的, bind(...)是不必要的。


只要有可能,在子注射器中创建的即时绑定将在祖先注射器中创建。 这意味着,没有bind(SampleInjectedClass.class); 行, SampleInjectedClass的绑定在父注入器中创建。 由于父注入器没有你的TypeListener ,它不会被触发。


你能检查你的代码吗? 在我对Guice 3的测试中,我无法重现你所看到的。

另外,从TypeListener文档中,强调我的和错误的:

public abstract void hear (TypeLiteral<I> type, TypeEncounter<I> encounter)

当Guice遇到一个符合构造函数或成员注入的新类型时调用。 在注入器创建期间调用(或者如果Guice在运行时遇到类型并创建JIT绑定,则后缀)

尽管在创建注入器时立即将所有其他依赖项都调用到TypeListener上,但隐式(“即时”)绑定不会。

但是,根据我上面的示例,看起来,如果参数包含在提供者方法中,它将立即在同一个监听器上注册。 你能制作一个简短的自包含的例子来展示你所问​​的行为吗?

链接地址: http://www.djcxy.com/p/16931.html

上一篇: Guice TypeListener not notified about the injected class Type

下一篇: UIActivityViewController and UIDocumentInteractionController