具有依赖注入的NullPointerException

时间:2011-10-19 22:29:53

标签: grails dependency-injection

我正在尝试使用依赖注入导出到“Export Plugin”提供的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)

我正在使用的代码如下,这只是意味着服务变量为空

def exportService// i have  tried with and without the initialization
        if(params?.format && 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
            }

除非我遗漏了一些非常基本的东西我不相信如果插件提供与服务相同的话,我应该实例化这个类。

由于

1 个答案:

答案 0 :(得分:3)

是的,你永远不应该实例化服务或其他Spring bean - 使用依赖注入。它可能有用,但如果bean有自己的依赖关系,那么它们将为null,因为你绕过了Spring。

你没有使用依赖注入,你正在声明一个局部变量并期待魔法。

Grails中的依赖注入使用公共字段。由于Groovy在getter和setter下创建了一个公共字段,所以Spring看到了setter,并且Grails被配置为按名称注入,所以只要字段/ setter匹配它工作的Spring bean名称。

所以你的控制器应该是这样的:

class MyController {

   def exportService

   def myAction = {
      if (params?.format && 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 bean。它已经注入了控制器(和taglib),在服务或其他bean中你只需要一个def grailsApplication字段声明。