将grails应用程序配置注入服务

将grails应用程序配置注入服务,grails,grails-controller,Grails,Grails Controller,我正在创建一个grails服务,它将通过Java库与第三方restapi交互。Java库需要通过url、用户名和密码为RESTAPI提供凭据 我希望将这些凭据存储在configuration/Config.groovy中,使其可用于服务,并确保在服务需要凭据之前,凭据可用于服务 我理解控制器可以使用grailsApplication.config,并且通过服务的方法可以向服务提供相关的配置值,例如: package example class ExampleController {

我正在创建一个grails服务,它将通过Java库与第三方restapi交互。Java库需要通过url、用户名和密码为RESTAPI提供凭据

我希望将这些凭据存储在
configuration/Config.groovy
中,使其可用于服务,并确保在服务需要凭据之前,凭据可用于服务

我理解控制器可以使用
grailsApplication.config
,并且通过服务的方法可以向服务提供相关的配置值,例如:

package example

class ExampleController {

    def exampleService

    def index = { }

    def process = {
        exampleService.setCredentials(grailsApplication.config.apiCredentials)
        exampleService.relevantMethod()
    }
}

我觉得这种方法有点缺陷,因为它依赖于控制器调用
setCredentials()
。自动将凭据提供给服务将更加健壮

这两个选项中的任何一个可行吗(我目前对grails不够熟悉):

  • 创建服务时,是否将
    grailsApplication.config.apiCredentials
    注入控制器中的服务

  • 在服务上提供某种形式的构造函数,允许在实例化时将凭据传递给服务


  • 将凭据注入服务是理想的选择。如何做到这一点?

    服务中提供了
    grailsApplication
    对象,允许:

    package example
    
    import com.example.ExampleApiClient;
    
    class ExampleService {
    
        def grailsApplication
    
        def relevantMethod() {
    
            def client = new ExampleApiClient(
                grailsApplication.config.apiCredentials.baseUrl
                grailsApplication.config.apiCredentials.username,
                grailsApplication.config.apiCredentials.password
            )
    
            return client.action();
        }
    }
    

    对于无法注入grailsApplication bean的上下文(服务不是其中之一,如Jon Cram所述),例如位于src/groovy中的helper类,您可以使用Holders类访问它:

    def MyController {
       def myAction() {
          render grailsApplication == grails.util.Holders.grailsApplication
       }
    }
    

    尽管可以将
    grailsApplication
    注入到服务中,但我认为服务不必处理配置,因为它更难测试,并且会破坏性能。另一方面,Spring可以以更健壮的方式处理配置和实例化。Grails在它的文档中有一个

    为了让您的示例使用Spring工作,您应该在
    resources.groovy中将您的服务注册为bean

    // Resources.groovy
    import com.example.ExampleApiClient
    
    beans {
        // Defines your bean, with constructor params
        exampleApiClient ExampleApiClient, 'baseUrl', 'username', 'password'
    }
    
    然后,您将能够将依赖项注入到您的服务中

    class ExampleService {
        def exampleApiClient
    
        def relevantMethod(){
            exampleApiClient.action()
        }
    }
    
    此外,在
    Config.groovy
    文件中,可以使用Grails约定覆盖配置语法上的任何bean属性:
    bean..


    Config.groovy
    resources.groovy
    都支持不同的环境配置。

    如果有办法注入实际的配置属性,而不是整个grailsApplication对象,那就更好了。请注意,我发现您需要在方法中使用grailsApplication.Config。[…]。否则,如果您尝试从方法之外的配置文件中提取数据,您将看到一个空指针。你的评论使我免于很多挫折。
    class ExampleService {
        def exampleApiClient
    
        def relevantMethod(){
            exampleApiClient.action()
        }
    }
    
    // Config.groovy
    ...
    beans.exampleApiClient.baseUrl = 'http://example.org'