首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在运行时设置数据源值

在运行时设置数据源值
EN

Stack Overflow用户
提问于 2013-07-29 03:52:24
回答 2查看 1.6K关注 0票数 1

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

以下是我尝试过的方法:

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

代码语言:javascript
复制
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:

代码语言:javascript
复制
beans = {
    parseDataSource(appfog.ParseDataSource) {
        grailsApplication = ref('grailsApplication')
    }
}

class ParseDataSource {
    def grailsAPplication
    ...
}

我也试过通过持有者获得它:

代码语言:javascript
复制
    GrailsApplication grailsApplication = Holders.grailsApplication

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

EN

回答 2

Stack Overflow用户

发布于 2013-07-29 22:50:33

我认为你把这件事搞得过于复杂了。在构建过程中覆盖grails配置对象会导致操作顺序问题,这会使代码非常脆弱。

直接设置这些值看起来更简单:

Datasource.groovy:

代码语言:javascript
复制
def configJson = JSON.parse(java.lang.System.getenv("VCAP_SERVICES"))
def mysqlConfig = configJson["mysql-5.1"][0].credentials

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

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

配置解析:

代码语言:javascript
复制
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中:

代码语言:javascript
复制
def parser = new EnvironmentConfigParser()

dataSource = {
    production = {
        username = parser.username
        // etc
    }
}
票数 1
EN

Stack Overflow用户

发布于 2013-07-29 08:31:45

只要您将bean parseDataSource注入到应用程序中的任何构件中的某个位置,您就应该能够以您在resources.groovy中注入的方式访问grailsApplication

在您的特殊情况下,需要在datasource.groovy中提供bean。您正在实例化POGO,这将不会帮助您将grailsApplication注入POGO。另一方面,您实际上不能像这样将POGO注入到datasource.groovy

def parseDataSource

因为它(数据源)在引导过程中是一个配置对象。

最好的方法仍然是在BootStrapmetaClass pogo,并使grailsApplication对其可用。伯特的shown it here就是这样的。

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

代码语言:javascript
复制
//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')
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17912200

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档