在共享一个通用插件的两个 grails 应用程序之间共享配置

Posted

技术标签:

【中文标题】在共享一个通用插件的两个 grails 应用程序之间共享配置【英文标题】:Share config between two grails apps that share a common plugin 【发布时间】:2014-02-16 00:47:38 【问题描述】:

我们将有两个应用程序都需要使用相同的服务/实用程序/代码/配置。

我们使用 grailsApplication.config.* 来配置外部服务的 URL 等内容。这些根据应用程序是否在 dev/test/qa/staging/prod 中运行而有所不同,因此我们使用了 Config.groovy 中的环境部分。我们需要为两个应用程序配置相同的 URL/环境。

为了避免重复,我们正在尝试构建一个插件来保存所有共享内容。这适用于服务等,但 Grails 插件不包含 Config.groovy、resources.groovy 所以所有的 URL 配置等都不能放在插件的 Config.groovy 中。

有没有一种很好的方法可以将该配置放在一个地方并让两个应用程序都可以使用它?

也许我们可以将它放在插件中的某个位置,然后将其“导入”到两个应用程序的 Config.groovy 中?

【问题讨论】:

您希望配置存在于插件中吗?抱歉,正在尝试了解此处的设置。 我已经重写了这个问题,以便更清楚。插件中的配置会很好,因此我们可以避免在两个应用程序中重复它。 【参考方案1】:

鉴于您想将配置嵌入到插件中,您需要使您的插件足够智能以读取它自己的配置并将其合并到包含的应用程序配置中。以下基于 Grails 1.3.7。从那时起,配置持有人可能已经发生了变化(2.0 做了很多房屋清洁工作),但我相信你可以弄清楚那部分。此示例假定您的插件中有一个名为 grails-app/conf/MyPluginConfig.groovy 的配置文件。

在您的 /MyPlugin.groovy 中,您将在 doWithSpring 闭包中添加您的配置合并。

def doWithSpring = 
    // get the current application configuration
    def currentConfig = org.codehaus.groovy.grails.commons.ConfigurationHolder.config
    GroovyClassLoader classLoader = new GroovyClassLoader(getClass().classLoader)

    // get the plugin configuration
    def pluginConfig = new ConfigSlurper(grails.util.GrailsUtil.environment).parse(classLoader.loadClass('MyPluginConfig'))

    // merge the configurations
    pluginConfig.merge(currentConfig)

    // set the application configuration to the merged configuration
    org.codehaus.groovy.grails.commons.ConfigurationHolder.config = pluginConfig

简而言之就是这样。希望这可以帮助。

另外,请注意,由于合并的完成方式,您仍然可以覆盖包含应用程序中的值。应用程序配置合并到插件配置中。如果包含的应用程序定义了某些内容,它将覆盖插件值。

【讨论】:

同意。我们的 grails 应用程序主要由插件组成。每个都有自己的默认值(即使是在两个应用程序之间共享的默认值)。合并默认配置和 可能 由客户端放置的配置让我们记录我们的默认设置和适当的标签,以便客户端覆盖默认设置。效果很好。 这与应用程序本身的外部配置文件相结合,在我的经验中是一个成功的组合。【参考方案2】:

外部配置文件的grails.config.locations 定义可以包括java.lang.Class 对象以从预编译的Groovy 脚本加载配置,以及file:classpath: URL 以在运行时解析Groovy 或.properties 文件。所以你应该可以在src/groovy下的插件中创建配置文件

plugin/src/groovy/com/example/CommonConfiguration.groovy

package com.example

environments 
  production 
    ...
  
  development 
    ...
  

然后在应用程序的Config.groovy 文件中将此类包含在grails.config.locations

grails.config.locations = [com.example.CommonConfiguration]

但这确实意味着当插件的CommonConfiguration 和宿主应用的Config.groovy 都为相同的属性指定一个值时,插件 会胜出。要解决平衡问题,您需要在 grails.config.locations 中添加第二个外部(可以是另一个 Class 或 URL)

grails.config.locations = [com.example.CommonConfiguration,
                           "file:app-config.groovy"]

然后将应用配置放在那里(因为后面的外部会覆盖早期的)。

【讨论】:

注意,grails.config.locations 必须是 config.groovy 的最后一行,这样外部配置才能覆盖所有内容 @johnSmith 不,它可以去任何地方。先解析整个Config.groovy,然后从解析的config中提取grails.config.locations的值,然后依次解析每个external并合并到main中。

以上是关于在共享一个通用插件的两个 grails 应用程序之间共享配置的主要内容,如果未能解决你的问题,请参考以下文章

如何与内部 svn 存储库共享自定义 Grails 插件?

扩展 Grails 插件的功能

在 Grails 中扩展具有一对多关系的域类

Grails:Spring Security 插件对于简单的安全性来说是不是过于强大

Grails:如何引用位于已安装插件中的资源?

GORM 无法实现插件中的域类是 GORM 类