Sco*_*ott 2 grails spring dependency-injection
我遇到了一个我在另一个项目中遇到的情况,我不确定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");
}
}
Run Code Online (Sandbox Code Playgroud)
到目前为止很标准,我有N豆,我想顺序调用来做工作.(这个例子显然是微不足道的).在另一个Java类中,我可以做一些魔术来将所有bean注入(自动装配)作为数组.
@Autowired(required=false)
private BaseInterface[] theWorkers;
Run Code Online (Sandbox Code Playgroud)
只要我将它们添加到配置中的bean容器中,这将为我提供一系列工作bean.
现在我想在Grails中做同样的事情.相同的公式不起作用.将@Autowired部分放入服务中,并在resources.groovy中创建Impl1和Impl2似乎不起作用.所以我想知道最好的解决方案是什么:
1)我遗漏了一些简单易用的东西.
2)做一些类似什么的duffymo建议的东西在这里.我在resources.groovy中创建了一个使用自定义工厂的命名bean.该工厂将发出一个包含实现某个接口的所有类的类.我会使用类似于建议来提取符合条件的服务/类,然后让该服务允许某人迭代它的子类来完成工作.
3)为resources.groovy中的每个Impl#类创建一个命名bean,然后只使用它们的不同名称并将它们全部注入到各个类中.这个选项不会真正扩展或给予太大的动力,但会起作用.
如果您可以访问Spring应用程序上下文,则可以调用getBeansOfType它返回实现指定接口或扩展指定基类的所有已知bean.所以我会注册每个bean,resources.groovy但也是一个管理器类,它获取对应用程序上下文的引用,并为您找到接口实现.你说你想按顺序调用它们,所以你也应该实现这个Ordered接口.
这是经理类(将它放在src/groovy /包中的正确文件夹中,并将其重命名为您想要的任何内容):
package com.foo
import org.springframework.beans.factory.InitializingBean
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
class BaseInterfaceManager implements ApplicationContextAware, InitializingBean {
ApplicationContext applicationContext
List<BaseInterface> orderedImpls
void afterPropertiesSet() {
orderedImpls = applicationContext.getBeansOfType(BaseInterface).values().sort { it.order }
}
}
Run Code Online (Sandbox Code Playgroud)
然后更改bean以便它们实现Ordered:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
和
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;
}
}
Run Code Online (Sandbox Code Playgroud)
注册所有三个resources.groovy(使用你想要的任何bean名称):
beans = {
impl1(Impl1)
impl2(Impl2)
baseInterfaceManager(BaseInterfaceManager)
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以在服务或控制器中添加依赖项注入或baseInterfaceManagerbean的任何内容,并使用它按顺序遍历实现类:
class FooService {
def baseInterfaceManager
void someMethod() {
for (impl in baseInterfaceManager.orderedImpls) {
impl.doSomething()
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2625 次 |
| 最近记录: |