我有一个Grails应用程序需要运行一个可能会随时间推移的策略。我知道Spring是Grails的基础,所以我想知道我是否可以访问Spring的IoC容器,这样我就可以将xml文件中的实际依赖项外部化了(注意:我从来没有真正做过这个,但只知道它,所以我可能是遗漏了什么)。我的目标是能够执行以下操作:
class SchemaUpdateService {
public int calculateSomething(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
IStrategy strat = (IStrategy) ctx.getBean("mystrat");
}
}
然后在beans.xml文件中映射相应的实现。我认为Grails支持这一点。有没有人有关于这将如何工作的任何文件?我真的只需要Spring IoC库吗?它会起作用吗?谢谢!
答案 0 :(得分:5)
您可以在resources.xml
或resources.groovy
中定义您的bean。 grails documentation非常清楚如何访问Spring应用程序上下文。
答案 1 :(得分:4)
您可以使用
从任何Grails工件访问应用程序上下文ApplicationContext ctx = grailsApplication.mainContext
然后,您可以使用它来检索您感兴趣的豆类:
IStrategy strat = (IStrategy) ctx.getBean("mystrat")
在无法访问grailsApplication
的类中,您可以使用以下帮助程序来访问应用程序上下文及其中的bean
class SpringUtils {
static getBean(String name) {
applicationContext.getBean(name)
}
static <T> T getBean(String name, Class<T> requiredType) {
applicationContext.getBean(name, requiredType)
}
static ApplicationContext getApplicationContext() {
ApplicationHolder.application.mainContext
}
}
但是,只有在运行时需要检索同一个bean的不同实现时才应该这样做。如果在编译时知道所需的bean,只需将bean连接到resources.xml
或resources.groovy
答案 2 :(得分:4)
首先,您要在grails-app/conf/spring/resources.groovy
中定义策略:
beans = {
myStrat(com.yourcompany.StrategyImpl) {
someProperty = someValue
}
}
然后,您只需def
您的服务中具有相同名称的媒体资源:
class SomeGrailsService {
def myStrat
def someMethod() {
return myStrat.doSomething()
}
}
在任何Grails工件(例如服务和域类)中,Grails会自动为myStrat
属性提供正确的值。但是不要忘记,在单元测试中,你必须手动给它一个值,因为在单元测试中不会发生自动布线。
在Grails人工制品之外,您可以使用以下内容:
def myStrat = ApplicationHolder.application.mainContext.myStrat
在Grails 2.0中,Graeme等人不推荐使用*Holder
类(例如ApplicationHolder
和ConfigurationHolder
),因此我不太确定Grails 2.0的方法是什么会... ...