使用特定于环境的值配置Grails服务的最佳方法是什么?我相信有两种选择:
我在stackoverflow和其他地方看过几篇帖子,展示了如何做#1(在服务中访问grailsApplication)。其中一个帖子是:Inject grails application configuration into service。
但是,我认为这会使服务与Grails产生不必要的耦合。这是不是类似于在pojo中访问Spring的applicationContext而不是配置/注入值?而且,到目前为止,我还没有运气在服务类的单元测试中工作。
两本书都有注入属性的例子(方法#2)。 “Grails 2的权威指南”第10章“行动中的服务”一节显示了如何执行此操作,但没有特定于环境的值。书中的Groovy和Grails Recipes,第16-2节也显示了使用resources.groovy的一个例子,但我还没能让它工作。
以下博客文章也有一个很好的例子,但不是特定于环境的:http://ldaley.com/post/1253952347/getting-more-out-of-property-override-configuration。 Grails Reference的第15章也与这些示例一致,并展示了如何基于每个环境在bean上设置属性。
然而,任何一种方法的例子都不会以某种方式表达任何意见或理性。两种方法都没有利弊吗?注入方法不会更容易进行单元测试,更符合春天的做事方式吗?
森
答案 0 :(得分:1)
我会说使用你更舒服的。我倾向于直接从服务访问grailsApplication.config
,因为这可以使配置更加“语义”(因为想要更好的词),因为你可以在他们做的事情之后命名配置选项,而不是他们控制的豆子。如果两个(或更多)不同的bean需要知道站点管理员的电子邮件地址(例如),那么他们都可以阅读grailsApplication.config.myapp.admin.email
而不是我必须单独配置beans.monitorService.destinationEmail
和beans.userService.fromEmail
。
在单元测试中,无论如何都必须模拟grailsApplication
配置,因此填写服务需要读取的配置选项的测试值并不是什么大不了的事。
答案 1 :(得分:0)
服务概念(服务文件夹中存在的类)和resources.groovy
中定义的Spring Bean存在差异。
要services,Grails已经设置了交易:
服务通常涉及域之间的协调逻辑 类,因此经常涉及跨越大的持久性 操作。鉴于服务的性质,他们经常需要 交易行为。您可以使用程序化事务 withTransaction方法,但这是重复的,但不是 充分利用Spring的底层交易的力量 抽象。
您声明的Spring Bean默认情况下不是事务性的。
“但是,我认为这会产生不必要的服务耦合 致Grails“
由于Grails服务与Spring Bean不同,我认为使用方法#1没有问题。
对于单元测试,您需要手动连接服务实例。例如:
class MyService {
def grailsApplication
}
class MyServiceTests {
MyService getServiceInstance() {
MyService myService = new MyService()
myService.grailsApplication = grailsApplication //static attribute in unit tests
return myService
}
}