1

所以本质上我正在尝试让我的项目在 AppFog 上启动并运行。数据源信息存储在环境变量中,本质上是 JSON。我的目标是获取这些数据并从中设置我的数据源配置。

这是我尝试过的:

设置数据源配置的代码,这是 POGO 中的一种方法。实例化 POGO 并在 DataSource.groovy 开头调用该方法:

import appfog.ParseDataSource
new ParseDataSource().setConfig()

dataSource {
...
}

class ParseDataSource {

    void setConfig() {
        String env = java.lang.System.getenv("VCAP_SERVICES")
        if (env) {
            def config = JSON.parse(env)
            config = config["mysql-5.1"][0].credentials
            grailsApplication.config.environments.production.dataSource.username = config.username
            grailsApplication.config.environments.production.dataSource.password = config.password
            grailsApplication.config.environments.production.dataSource.url = "jdbc:mysql://" + config.host + ":" + config.port + "/" + config.name
        }
    }
}

问题是 grailsApplication 始终为空。我试过在resources.groovy 中注册一个spring bean:

beans = {
    parseDataSource(appfog.ParseDataSource) {
        grailsApplication = ref('grailsApplication')
    }
}

class ParseDataSource {
    def grailsAPplication
    ...
}

我也尝试过通过 Holders 获得它:

    GrailsApplication grailsApplication = Holders.grailsApplication

无论哪种方式,它都是空的,所以我没有做正确的事情。有任何想法吗?

4

2 回答 2

1

我认为您使这过于复杂。在构建过程中覆盖 grails 配置对象会导致操作顺序问题,从而使代码非常脆弱。

简单地直接设置值似乎更简单:

数据源.groovy:

def configJson = JSON.parse(java.lang.System.getenv("VCAP_SERVICES"))
def mysqlConfig = configJson["mysql-5.1"][0].credentials

dataSource = {
    production = {
        username = mysqlConfig.username
        // etc.
    }
}

如果为了清楚起见,您想在自己的类中继续解析,请创建 values 属性并在dataSource块中读取它们,而不是尝试将它们放在 grails 配置对象中:

配置解析:

class EnvironmentConfigParser {
    String username
    String password
    String url

    EnvironmentConfigParser() {
        def configJson = JSON.parse(java.lang.System.getenv("VCAP_SERVICES"))
        def mysqlConfig = configJson["mysql-5.1"][0].credentials

        username = mysqlConfig.username
        password = mysqlConfig.password
        url = "jdbc:mysql://${mysqlConfig.host}:${mysqlConfig.port}/${mysqlConfig.name}"
    }
}

在 Datasource.groovy 中:

def parser = new EnvironmentConfigParser()

dataSource = {
    production = {
        username = parser.username
        // etc
    }
}
于 2013-07-29T14:50:33.417 回答
0

您应该能够访问grailsApplication您在 resources.groovy 中注入的方式,前提是您将 bean 注入到parseDataSource应用程序中的任何工件中的某个位置。

在您的特殊情况下,您需要 bean 在datasource.groovy. 您正在实例化 POGO,这不会帮助您注入grailsApplicationPOGO。另一方面,您实际上不能注入 POGO 来点datasource.groovy

def parseDataSource

因为它(数据源)是引导期间的配置对象。

最好的方法仍然是向metaClasspogo 提供BootStrapgrailsApplication提供给它。伯特在这里就以这种方式展示了它。

我也在考虑BeanPostProcessor在这种情况下是否有用,但我不确定是否会实现每个环境的配置。但是,如果它有助于满足您的业务需求,您可以尝试一下。它通常是这样的:

//src/groovy
import org.springframework.beans.factory.config.BeanPostProcessor
class DatasourcePostProcessor implements BeanPostProcessor{
    def parseDataSource
    @Override
    Object postProcessBeforeInitialization(Object bean, String beanName) {
        return bean
    }

    @Override
    Object postProcessAfterInitialization(Object bean, String beanName) {
        if(beanName == 'dataSource') {
           //Set values to dataSource bean as required
           parseDataSource.setConfig(bean) 
        }
        return bean
    }
}

//resources.groovy
parseDataSource(ParseDataSource){
    grailsApplication = ref('grailsApplication')
}

datasourcePostProcessor(DatasourcePostProcessor){
    parseDataSource = ref('parseDataSource')
}
于 2013-07-29T00:31:45.163 回答