这里有Grails 2.4.5。我做了一个grails create-service com.example.service.Simple,为我创建了一个SimpleService,然后将其修改为:

class SimlpeService {
    SimpleClient simpleClient

    Buzz doSomething(String derp) {
        // ...
        Fizz fizz = simpleClient.doSomething(derp)
        // ...
        fizz.asBuzz()
    }
}

我现在可以使用SimpleService“注入(inject)” Controller ,如下所示:
class MyController {
    SimpleService simpleService

    def index() {
        // etc...
    }
}

但是,如何配置/连接正确的SimpleService实例的SimpleClient。让我们假设SimpleClient通常是这样构建的:
SimpleClient simpleClient = SimpleClientBuilder
    .withURL('http://simpleclientdev.example.com/simple')
    .withAuth('luggageCombo', '12345')
    .isOptimized(true)
    .build()

根据我所处的环境,我可能希望SimpleClient实例连接到simpleclientdev.example.comsimpleclientqa.example.com甚至是simpleclient.example.com。另外,我可能会使用不同的身份验证凭据,并且可能/可能不希望对其进行“优化”等。重点是:如何将SimpleServiceSimpleClient实例一起注入(inject)?

最佳答案

您可以在服务中的一种方法上使用Java的PostConstruct批注来完成所需的工作。从文档:



SimpleService.groovy

import javax.annotation.PostConstruct

class SimlpeService {

    private SimpleClient simpleClient

    def grailsApplication

    @PostConstruct
    void postConstruct() {
        def config = grailsApplication.config.client.data

        SimpleClient simpleClient = SimpleClientBuilder
            .withURL(config.url)
            .withAuth('luggageCombo', config.username)
            .isOptimized(config.optimized)
            .build()
    }

    Buzz doSomething(String derp) {
        // ...
        Fizz fizz = simpleClient.doSomething(derp)
        // ...
        fizz.asBuzz()
    }
}

因此,当解析了该服务的所有依赖项(在本例中为postConstruct())并调用了任何服务方法时,Grails或Spring将自动调用此方法grailsApplication
注意,访问任何SimpleService的字段成员或方法之前,必须先调用方法。

现在,一切都已经像您提到的那样进行了配置,您可能需要使用不同的凭据来调用不同的URL,只需要在Config.groovy中将它们定义为:
environments {
    development {
        client {
            data {
                url = "simpleclientdev.example.com"
                username = "test"
                optimized = false
            }
        }
    }
    production {
        client {
            data {
                url = "simpleclient.example.com"
                username = "johndoe"
                optimized = true
            }
        }
    }
}

现在,当您在开发模式下执行run-app并在示例 Controller 中调用simpleService.doSomething()时,将自动使用测试证书来访问simpleclientdev.example.com URL,并且在使用生产环境进行部署时,相同的simpleService.doSomething()方法将在simpleclient.example.com设置为optimized的情况下访问true

更新
根据您的问题,此处的关键点是我们不会注入(inject)SimpleService的不同实例,因为默认情况下服务是单例的。相反,我们根据环境更改与服务关联的值。

07-28 03:47