Внедрить конфигурацию приложения Grails в сервис - PullRequest
37 голосов
/ 11 февраля 2011

Я создаю сервис grails, который будет взаимодействовать со сторонним REST API через библиотеку Java.Для библиотеки Java требуются учетные данные для API REST с помощью URL, имени пользователя и пароля.

Я хотел бы сохранить эти учетные данные в configuration/Config.groovy, сделать их доступными для службы и убедиться, что учетные данные доступныв службу, прежде чем она потребует их.

Я ценю, что grailsApplication.config доступно для контроллеров и что с помощью метода службы соответствующие значения конфигурации могут быть предоставлены службе, например:

package example

class ExampleController {

    def exampleService

    def index = { }

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


package example

import com.example.ExampleApiClient;

class ExampleService {

    def credentials

    def setCredentials(credentials) {
        this.credentials = credentials
    }

    def relevantMethod() {

        def client = new ExampleApiClient(
            credentials.baseUrl,
            credentials.username,
            credentials.password
        )

        return client.action();
    }
}

Я чувствую, что этот подход немного ошибочен, поскольку зависит от вызова контроллера setCredentials().Автоматическое предоставление учетных данных для службы было бы более надежным.

Возможен ли любой из этих двух вариантов (в настоящее время я недостаточно знаком с grails):

  1. InjectgrailsApplication.config.apiCredentials в службу в контроллере при создании службы?

  2. Предоставить некоторую форму конструктора в службе, которая позволяет передавать учетные данные в службу во время создания экземпляра?

Внедрение учетных данных в сервис идеально.Как это можно сделать?

Ответы [ 3 ]

79 голосов
/ 12 февраля 2011

Объект 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();
    }
}
11 голосов
/ 23 сентября 2014

Даже если grailsApplication может быть введено в службы, я думаю, что службы не должны иметь дело с конфигурацией, потому что ее сложнее тестировать и нарушает принцип единой ответственности . Spring, с другой стороны, может обрабатывать конфигурацию и реализацию более надежным способом. Grails имеет выделенный раздел в своих документах.

Чтобы ваш пример работал с использованием Spring, вы должны зарегистрировать свой сервис в качестве компонента в resources.groovy

// 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 над синтаксисом конфигурации: beans.<beanName>.<property>:

// Config.groovy
...
beans.exampleApiClient.baseUrl = 'http://example.org'

И Config.groovy, и resources.groovy поддерживают различные конфигурации среды.

4 голосов
/ 06 июня 2014

В тех случаях, когда вы не можете внедрить bean-компонент grailsApplication (служба не относится к числу тех, что описаны Jon Cram), например вспомогательный класс, расположенный в src / groovy, вы можете получить к нему доступ с помощью держателей класс:

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