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 が常に null であることです。Resources.groovyにSpring Beanを登録しようとしました:

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

class ParseDataSource {
    def grailsAPplication
    ...
}

また、ホルダー経由で取得しようとしました:

    GrailsApplication grailsApplication = Holders.grailsApplication

どちらにしても null なので、私は正しいことをしていません。何か案は?

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.
    }
}

明確にするために独自のクラスで解析を続けたい場合は、値のプロパティを作成し、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

アプリケーションの任意のアーティファクトにgrailsApplicationBean を注入している場合は、resources.groovy に注入した方法にアクセスできるはずです。parseDataSource

特別なケースでは、Bean を で使用できるようにする必要がありますdatasource.groovy。POGO への注入に役立たない POGO をインスタンス化していgrailsApplicationました。一方、POGO をdatasource.groovy好きなように実際に注入することはできません。

def parseDataSource

それ(データソース)はブートストラップ中の構成オブジェクトであるためです。

残っている最善の方法はmetaClass、ポゴに行き、それ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 に答える