Правильный способ автоматического подключения сервисов к командным объектам в Grails при создании внутри контроллера

#spring #grails

#весна #grails

Вопрос:

У меня есть такой код…

 @Validateable
class RecipientsCommand {
 ...
 EmailService emailService
 void getEmailEligibleRecipients(Long accountId){
    emailService.loadEligibleEmail(accountId) 
 }
}
 

resource.groovy

 imports com.test.commands.RecipientsCommand
beans = {
 recipientsCommand(RecipientsCommand){bean -> bean.autowire = true}
}
 

Но служба по-прежнему всегда равна нулю, когда я вызываю

 new RecipientCommand()
 

Поскольку объект Command, по-видимому, является интерфейсом между представлениями и контроллером, я создаю его, заполняю и передаю в представление. Затем я использую его для анализа и сохранения данных. Если я изменю на…

 EmailService emailService = new EmailService()
 

Все работает нормально.

Ответ №1:

Автоматическое подключение происходит только тогда, когда Grails создает экземпляр для вас. Вы не можете просто new RecipientCommand() ожидать, что Spring будет участвовать в этом. Если вы извлекаете recipientsCommand компонент из контекста приложения Spring, он будет автоматически подключен, и если RecipientCommand он создается фреймворком и передается в качестве аргумента вашему действию контроллера, это также будет автоматически подключено. вызов new RecipientCommand() конструктора приведет к созданию нового экземпляра, который не подключается автоматически.

Редактировать:

Примеры…

 class SomeController {
    def someAction(RecipientCommand co) {
        // co will already be auto wired
        // this approach does NOT require you to have defined the 
        // recipientsCommand bean in resources.groovy
    }
}

class SomeOtherController {
    def someAction() {
        // rc will be autowired
        // this approach requires you to have defined the 
        // recipientsCommand bean in resources.groovy
        def rc = grailsApplication.mainContext.getBean('recipientsCommand')
    }
}

class AnotherSomeOtherController {
    def recipientsCommand

    def someAction() {
        // recipientsCommand will be auto wired
        // this approach requires you to have defined the
        // recipientsCommand bean in resources.groovy
    }
}

class YetAnotherController {
    def someAction() {
        // rc will not be autowired
        def rc = new RecipientCommand()
    }
}
 

Надеюсь, это поможет.

Комментарии:

1. Имеет ли значение пакет? Например, моя команда находится в одном пакете, а мой контроллер — в другом?

2. Нет, это не имеет значения, находятся ли объект command и контроллер в одном пакете.