如何使用 Guice 使 Multibinder 与 FactoryModuleBuilder 和泛型一起工作?

How to make Multibinder work with FactoryModuleBuilder and Generics using Guice?

我读过 Google guice - multibinding + generics + assistedinject 但它似乎没有回答我的具体情况。这是我拥有的:

FactoryModuleBuilder

一起使用的接口
public interface IFilterFactory<T extends IFilter> {
    T create(FilterConfig config);
}
public interface IFilterOneFactory extends IFilterFactory<FilterOne> {}
public interface IFilterTwoFactory extends IFilterFactory<FilterTwo> {}

我的 Guice 模块:

@Override
protected void configure() {
    install(new FactoryModuleBuilder().build(IFilterOneFactory.class));
    install(new FactoryModuleBuilder().build(IFilterTwoFactory.class));

    Multibinder<IFilterFactory<?>> filterBinder = Multibinder.newSetBinder(binder(), new TypeLiteral<IFilterFactory<?>>() {});
    filterBinder.addBinding().to(IFilterOneFactory.class);
    filterBinder.addBinding().to(IFilterTwoFactory.class);
}

我的主过滤器应该结合所有其他过滤器:

public class MainFilterFactory {
    @Inject
    MainFilterFactory(Set<IFilterFactory<?>> factories) {
        this.factories = factories;
    }

    public MainFilter get(String groupKey) {
        FilterConfig fc = new FilterConfig(groupKey);
        IFilter[] filters = this.factories.stream().map(f -> f.create(fc)).toArray(IFilter[]::new);
        return new MainFilter(Arrays.asList(filters));
    }
}

这实际上行不通。我得到以下堆栈跟踪:

[WARNING]
java.lang.reflect.InvocationTargetException
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.codehaus.mojo.exec.ExecJavaMojo.run(ExecJavaMojo.java:297)
        at java.lang.Thread.run(Thread.java:745)
[WARNING]
com.google.inject.internal.util.$ComputationException: java.lang.ArrayIndexOutOfBoundsException: 19640
        at com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:553)
        at com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:419)
        at com.google.inject.internal.util.$CustomConcurrentHashMap$ComputingImpl.get(CustomConcurrentHashMap.java:2041)
        at com.google.inject.internal.util.$StackTraceElements.forType(StackTraceElements.java:70)
        at com.google.inject.internal.Errors.formatSource(Errors.java:687)
        at com.google.inject.internal.Errors.format(Errors.java:555)
        at com.google.inject.CreationException.getMessage(CreationException.java:48)
        at java.lang.Throwable.getLocalizedMessage(Throwable.java:391)
        at java.lang.Throwable.toString(Throwable.java:480)
        at java.lang.String.valueOf(String.java:2982)
        at java.lang.StringBuilder.append(StringBuilder.java:131)
        at java.lang.Throwable.printEnclosedStackTrace(Throwable.java:695)
        at java.lang.Throwable.printStackTrace(Throwable.java:667)
        at java.lang.Throwable.printStackTrace(Throwable.java:643)
        at org.apache.maven.cli.PrintStreamLogger.warn(PrintStreamLogger.java:131)
        at org.apache.maven.monitor.logging.DefaultLog.warn(DefaultLog.java:93)
        at org.codehaus.mojo.exec.ExecJavaMojo$IsolatedThreadGroup.uncaughtException(ExecJavaMojo.java:386)
        at org.codehaus.mojo.exec.ExecJavaMojo.run(ExecJavaMojo.java:309)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 19640
        at com.google.inject.internal.asm.$ClassReader.<init>(Unknown Source)
        at com.google.inject.internal.asm.$ClassReader.<init>(Unknown Source)
        at com.google.inject.internal.asm.$ClassReader.<init>(Unknown Source)
        at com.google.inject.internal.util.$LineNumbers.<init>(LineNumbers.java:62)
        at com.google.inject.internal.util.$StackTraceElements.apply(StackTraceElements.java:36)
        at com.google.inject.internal.util.$StackTraceElements.apply(StackTraceElements.java:33)
        at com.google.inject.internal.util.$MapMaker$StrategyImpl.compute(MapMaker.java:549)
        ... 18 more

我是不是做错了什么?

这实际上是 Guice 3.0 和 Java 8 之间的 Guice 兼容性问题。 参见:https://github.com/google/guice/issues/757

我在构造函数中遗漏了一些 @Assisted@Inject 并且 Guice 未能报告错误,因为在那些 类.

中使用了一些 lambdas

评论 lambda 使我能够看到错误并修复它们。然后我取消注释它们,一切似乎都按预期工作。