环境特定的 Grails 服务配置

Posted

技术标签:

【中文标题】环境特定的 Grails 服务配置【英文标题】:Environment Specific Grails Service Configuration 【发布时间】:2013-07-13 14:51:12 【问题描述】:

使用环境特定值配置 Grails 服务的最佳方式是什么?我相信有两种选择:

    从服务类中访问 grailsApplication 值或 在 Config.groovy 或 resources.groovy 的 bean 闭包中配置服务 bean。

我在 *** 和其他地方看到了一些帖子,这些帖子展示了如何执行 #1(在服务中访问 grailsApplication)。一个这样的帖子是:Inject grails application configuration into service。

但是,我认为这会造成服务与 Grails 的不必要耦合。这不是类似于在 pojo 中访问 Spring 的 applicationContext 而不是配置/注入值吗?此外,到目前为止,我还没有任何运气让它在服务类的单元测试中工作。

两本书都有注入属性的示例(方法#2)。 The Definitive Guide to Grails 2,第 10 章,标题为“Services in Action”的一本书展示了如何做到这一点,但没有特定于环境的值。 Groovy and Grails Recipes 一书,第 16-2 节也展示了一个使用 resources.groovy 的示例,但我还不能让它工作。

以下博客文章也有一个很好的示例,但不是特定于环境的:http://ldaley.com/post/1253952347/getting-more-out-of-property-override-configuration。 Grails 参考的第 15 章也与这些示例一致,并展示了如何在每个环境的基础上设置 bean 的属性。

但是,任何一种方法的示例都没有给出任何意见或理由来以某种方式进行。这两种方法真的没有优点和缺点吗?注入方式不是更容易单元测试,更符合spring的做事方式吗?

内森

【问题讨论】:

【参考方案1】:

我会说使用你更舒服的那个。我倾向于直接从服务访问grailsApplication.config,因为这可以让您使配置更加“语义化”(因为需要更好的词),因为您可以根据它们所做的事情命名配置选项,而不是他们控制哪个bean。如果两个(或更多)不同的 bean 需要知道站点管理员的电子邮件地址(例如),那么它们都可以读取grailsApplication.config.myapp.admin.email,而不是我必须分别配置beans.monitorService.destinationEmailbeans.userService.fromEmail

在单元测试中,无论如何您都必须模拟 grailsApplication 配置,因此为您的服务需要读取的配置选项填充测试值没什么大不了的。

【讨论】:

谢谢,这实际上是有道理的。最后,该方法的一些合理性! 根据您的说法,grails 的发明者似乎发生了思维转变,因为您描述的问题类型是重复值,这些值在弹簧配置中应该是相同的值。因此,对基本集中在 grailsApplication 下的配置值的引用是一个实际的改进。也许使用 groovy 设置比使用 Java 更容易,否则在 Spring 中也可能是一个选项。 @NathanWard 覆盖配置方法在某些情况下非常有用,主要是当您想将属性值注入到您无法控制的 bean 中时(例如,由插件提供的那些)。【参考方案2】:

服务(存在于服务文件夹中的类)的概念与resources.groovy 中定义的 Spring Beans 的概念有所不同。

致services,Grails 已设置事务:

服务通常涉及域之间的协调逻辑 类,因此经常涉及跨越大范围的持久性 操作。鉴于服务的性质,他们经常需要 交易行为。您可以将程序化事务与 withTransaction 方法,但是这是重复的,不会 充分利用 Spring 底层事务的力量 抽象。

默认情况下,您声明的 Spring Bean 不是事务性的。

“但是,我认为这会造成不必要的服务耦合 到 Grails"

由于 Grails 服务与 Spring Beans 不同,我认为使用方法 #1 没有问题。

对于单元测试,您需要手动连接您的服务实例。示例:

class MyService 
  def grailsApplication


class MyServiceTests 
  MyService getServiceInstance() 
    MyService myService = new MyService()
    myService.grailsApplication = grailsApplication //static attribute in unit tests
    return myService
  

【讨论】:

感谢您的回复。我仍然认为 Grails 服务概念与基于 Martin Fowler 的企业架构模式中的同名模式的服务层概念相同。 概念可以相同,但Grails Service和Grails Spring Bean不一样。

以上是关于环境特定的 Grails 服务配置的主要内容,如果未能解决你的问题,请参考以下文章

生产环境中的 Grails 服务返回 Null

使用“gradle test”测试 Grails 3 应用程序使用错误的环境配置

Grails - 模式配置

Grails 3.0.1 不支持 application.yml mongo 配置

排除特定环境的插件

Grails Spring Security - 登录后总是重定向到特定页面?