将从共享接口继承的多个Springbean注入到服务内的一个数组中

将从共享接口继承的多个Springbean注入到服务内的一个数组中,spring,grails,dependency-injection,Spring,Grails,Dependency Injection,我在另一个项目中遇到了一种情况,我不确定在Grails中最好的方法是什么。为了建立它,这就是我在一个纯Spring项目中所做的 我有两个从同一接口继承的类: public interface BaseInterface { void doSomething(); } public class Impl1 implements BaseInterface { public void doSomething(){ System.out.println("doing

我在另一个项目中遇到了一种情况,我不确定在Grails中最好的方法是什么。为了建立它,这就是我在一个纯Spring项目中所做的

我有两个从同一接口继承的类:

public interface BaseInterface {
    void doSomething();
}

public class Impl1 implements BaseInterface {
    public void doSomething(){
        System.out.println("doing impl 1");
    }
}

public class Impl2 implements BaseInterface {
    public void doSomething(){
        System.out.println("doing impl 2");
    }
}
到目前为止,我有N个bean,我想按顺序调用它们来完成工作。(这个例子显然微不足道)。在另一个Java类中,我可以做一些魔术,将所有bean作为数组注入()

@Autowired(required=false)
    private BaseInterface[] theWorkers;
这将给我一个工作bean数组,只要我已经将它们添加到配置中的bean容器中

现在我正试图在Grails中做同样的事情。同样的公式不起作用。将@Autowired部分放在服务中,并在resources.groovy中创建Impl1和Impl2似乎无法完成这项工作。所以我想知道最好的解决方案是什么:

1) 我错过了一些简单的东西,可以让这项工作非常容易

2) 做一些类似于达菲莫建议的事情。我将在resources.groovy中创建一个使用自定义工厂的命名bean。该工厂将发出一个类,该类将包含实现某个接口的所有类。我会使用类似于建议的方法来提取符合条件的服务/类,然后让该服务允许某人迭代它的子类来完成工作


3) 在resources.groovy中为每个Impl#类创建一个命名bean,然后只使用它们的不同名称,并将它们分别注入到类中。此选项不会真正扩展或提供太多动态性,但会起作用。

如果您能够访问Spring应用程序上下文,您可以调用
getBeansOfType
,它返回实现指定接口或扩展指定基类的所有已知bean。因此,我将在
resources.groovy
中注册每个bean,同时注册一个管理器类,该类获取对应用程序上下文的引用,并为您找到接口实现。您说过要按顺序调用它们,因此也应该实现
Ordered
接口

下面是manager类(将其放在src/groovy/中,放在包的正确文件夹中,并将其重命名为您想要的任何名称):

resources.groovy
中注册所有这三个bean(使用您想要的任何bean名称):

然后,您可以为
baseInterfaceManager
bean在服务或控制器中添加依赖项注入,并使用它按顺序循环实现类:

class FooService {

   def baseInterfaceManager

   void someMethod() {
      for (impl in baseInterfaceManager.orderedImpls) {
         impl.doSomething()
      }
   }
}

酷,我考虑的策略之一是将2个实现bean包装到另一个简单bean中。我更喜欢这个解决方案,因为BaseInterfaceManager不知道实现(或者有多少实现)。因此,只有resources.groovy需要更新,这正是我的目标。感谢您为Grails社区所做的一切,它真的很棒。
import org.springframework.core.Ordered;

public class Impl1 implements BaseInterface, Ordered {
   public void doSomething(){
      System.out.println("doing impl 1");
   }

   public int getOrder() {
      return 42;
   }
}
import org.springframework.core.Ordered;

public class Impl2 implements BaseInterface, Ordered {
   public void doSomething(){
      System.out.println("doing impl 2");
   }

   public int getOrder() {
      return 666;
   }
}
beans = {

   impl1(Impl1)
   impl2(Impl2)

   baseInterfaceManager(BaseInterfaceManager)
}
class FooService {

   def baseInterfaceManager

   void someMethod() {
      for (impl in baseInterfaceManager.orderedImpls) {
         impl.doSomething()
      }
   }
}