【问题标题】:How to get all implementors/subclasses of an interface with Guice?如何使用 Guice 获取接口的所有实现者/子类?
【发布时间】:2011-05-22 00:03:39
【问题描述】:

使用 Spring,您可以定义一个数组属性并让 Spring 注入从给定类型派生的每个 (@Component) 类。

Guice 中是否有类似的功能?还是添加此行为的扩展点?

【问题讨论】:

    标签: java guice


    【解决方案1】:

    这看起来像是 Guice MultiBinder 的用例。你可以有这样的东西:

    interface YourInterface {
        ...
    }
    
    class A implements YourInterface {
        ...
    }
    
    class B implements YourInterface {
        ...
    }
    
    class YourModule extends AbstractModule {
        @Override protected void configure() {
            Multibinder.newSetBinder(YourInterface.class).addBinding().to(A.class):
            Multibinder.newSetBinder(YourInterface.class).addBinding().to(B.class):
        }
    }
    

    你可以在任何地方注入Set<YourInterface>

    class SomeClass {
        @Inject public SomeClass(Set<YourInterface> allImplementations) {
            ...
        }
    }
    

    这应该与您的需要相匹配。

    【讨论】:

    • 确实如此。感谢您为我指明正确的方向。
    • 你会在一个单独的 jar(“guice 扩展”)中找到多重绑定:search.maven.org/…
    • 请问春天我们怎么做?
    【解决方案2】:

    Guice Multibindings 要求您将AB 的显式addBinding() 添加到YourInterface。如果您想要一个更“透明”(自动)的解决方案,例如 AFAIK Spring 提供的开箱即用的解决方案,那么假设 Guice 已经知道 AB,因为您已经有了 @987654330 的绑定@ & B 无论如何,即使不是明确的但只是隐含的,例如通过@Inject 其他地方,然后只有这样你才能使用类似的东西进行自动发现(inspired by as done here,基于accessing Guice injector in a Module):

    class YourModule extends AbstractModule {
       @Override protected void configure() { }
    
       @Provides
       @Singleton
       SomeClass getSomeClass(Injector injector) {
           Set<YourInterface> allYourInterfaces = new HashSet<>();
           for (Key<?> key : injector.getAllBindings().keySet()) {
               if (YourInterface.class.isAssignableFrom(key.getTypeLiteral().getRawType())) {
                YourInterface yourInterface = (YourInterface) injector.getInstance(key);
                allYourInterfaces.add(yourInterface);
           }
           return new SomeClass(allYourInterfaces);
       }
    }
    

    再次注意,这种方法不需要任何类路径扫描;它只是查看注入器中所有已知的绑定,以查找任何 IS-A YourInterface

    【讨论】:

    【解决方案3】:

    科特林

    Class SomeModule : AbstractModule() {
            
                override fun configure() {
                    val myBinder: Multibinder<MyInterface> = Multibinder.newSetBinder(binder(), MyInterface::class.java)
                    myBinder.addBinding().to(Implementation1::class.java)
                     myBinder.addBinding().to(Implementation2::class.java)
    }
    

    用法

    @Inject constructor(private val someVar:Set<@JvmSuppressWildcards MyInterface>)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-01-24
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 1970-01-01
      • 2016-05-13
      相关资源
      最近更新 更多