#grails #dependency-injection
#grails #внедрение зависимостей
Вопрос:
Я пытаюсь использовать внедрение зависимостей для экспорта в функциональность Excel, предоставляемую «Плагином экспорта», Кажется, что всякий раз, когда я пытаюсь использовать сервис в своем проекте, я получаю ошибку, подобную следующей
Stacktrace follows:
java.lang.NullPointerException: Cannot invoke method export() on null object
at pm.ProjectsController$_closure2.doCall(ProjectsController.groovy:39)
at pm.ProjectsController$_closure2.doCall(ProjectsController.groovy)
at java.lang.Thread.run(Thread.java:662)
Код, который я использую, следующий, это просто означает, что служебная переменная имеет значение null
def exportService// i have tried with and without the initialization
if(params?.format amp;amp; params.format != "html"){
response.contentType = ConfigurationHolder.config.grails.mime.types[params.format]
response.setHeader("Content-disposition", "attachment; filename=books.${params.extension}")
exportService.export(params.format, response.outputStream,projectsList, [:], [:])
}
Похоже, что в моем проекте не работает ни один плагин, который использует сервисы, например, AsynchronousMailService в моем проекте не работал так, как предполагалось, и поэтому я использовал его следующим образом
AsynchronousMailService asynchronousMailService = new AsynchronousMailService()
asynchronousMailService.sendAsynchronousMail {
to projectsInstance.projectLead.emailAddress
subject "New project is assigned to you"
html msg
}
Если я не пропускаю что-то очень простое, я не верю, что я должен создавать экземпляр этого класса, если плагин предлагает то же самое, что и service.
Спасибо
Ответ №1:
Правильно, вы никогда не должны создавать экземпляры сервисов или других компонентов Spring — используйте внедрение зависимостей. Это может сработать, но если у компонента есть какие-либо собственные зависимости, они будут нулевыми, поскольку вы обходите Spring.
Вы не используете внедрение зависимостей, вы объявляете локальную переменную и ожидаете волшебства.
Внедрение зависимостей в Grails использует общедоступные поля. Поскольку Groovy создает общедоступное поле в получателе и установщике под капотом, Spring видит установщик, а Grails настроен на ввод по имени, поэтому, пока поле / установщик соответствует имени компонента Spring, оно работает.
Итак, ваш контроллер должен выглядеть примерно так:
class MyController {
def exportService
def myAction = {
if (params?.format amp;amp; params.format != "html") {
response.contentType = grailsApplication.config.grails.mime.types[params.format]
response.setHeader("Content-disposition",
"attachment; filename=books.${params.extension}")
exportService.export(params.format,
response.outputStream,projectsList, [:], [:])
}
}
}
Обратите внимание, что я также удалил использование ConfigurationHolder, поскольку оно устарело. Лучший способ получить доступ к конфигурации — из grailsApplication
компонента. Оно уже внедрено в контроллеры (и теги), а в сервисе или другом компоненте вам просто понадобится def grailsApplication
объявление поля.