从 Grails Holders 类中获取服务 bean

Posted

技术标签:

【中文标题】从 Grails Holders 类中获取服务 bean【英文标题】:Get a service bean from Grails Holders class 【发布时间】:2014-11-21 20:18:43 【问题描述】:

我正在尝试将插件更新到 Grails 2.4。因此,我必须用较新的 Holders 类替换已弃用的 ApplicationContext 类。

但是我在从 Holders 类中获取服务 bean 时遇到了一些问题。

运行以下代码:

import grails.util.Holders;

def myService = Holders.grailsApplication.mainContext.myService

println myService
println myService.getClass()
println myService.serviceMethod()

它会打印如下内容:

grails.plugin.my.MyService@1e5cd54d 抛出异常

java.lang.NullPointerException 在 ConsoleScript2.run(ConsoleScript2:6) 在 org.springsource.loaded.ri.ReflectiveInterceptor.jlrMethodInvoke(ReflectiveInterceptor.java:1270)

当我同时调用“getClass”方法和“serviceMethod”方法时,它会抛出 NullPointerException。

我也尝试通过从 Eclipse 调试来查看发生了什么,我可以观察到“myService”变量被设置为一个对象。当我点击它时,我可以看到它的字符串表示,就像上面打印的一样。但我看不到物体内部的任何东西。这个服务类有成员变量,但我在调试时看不到它们。就像他们不在那里一样。

谁能解释我出了什么问题?

谢谢

【问题讨论】:

为什么不使用 grails 的依赖注入工具?例如,在创建控制器时,只需添加一个通过名称自动装配的类属性“def myService”。 因为我试图从一个非 grails artfact 类 (src/groovy) 访问这个 bean。所以自动装配不可用。 【参考方案1】:

不要使用Holders,并避免引入依赖项。使用依赖注入,这是一件好事。

您的src/groovy 类可能是从控制器、服务、Quartz 作业或其他支持 DI 的 Grails 工件调用的,对吧?如果是这样,请在此处注入此服务,当您调用 src/groovy 类时,将其作为方法参数传递,或者在构造函数或 setter 中注入一次。

即使它不是从 Grails 工件调用的,也很可能很容易访问该服务。例如。 servlet 可以访问ServletContext,从那里访问ApplicationContext 很简单。

【讨论】:

首先感谢您的回答。实际上这个类应该从我的插件外部调用。然后我认为从调用它的类初始化它不是一个好主意。关于 ServletContext 部分,它与从 Holders 类访问 ApplicationContext 有什么不同? 为什么不是个好主意?您编写插件,因此您定义 API 和使用规则。这可能不会是那么大的负担。您还可以将您的 src/groovy 类注册为 Spring bean(如果可能,则为单例,如果它是有状态的,则为原型,然后无论哪种方式都可以使用 DI)。使用 ServletContext 和 ApplicationContext 您仍然需要重新反转控制和拉动,但如果这是唯一的方法,那么这就是您需要做的。 Holders 的问题在于它与已弃用/删除的持有者的问题完全相同。 好吧,我想避免设置方法。不过我喜欢豆子的。如果我可以让这个类成为原型 bean,那就太好了。但是如果插件层次结构中没有“resources.groovy”文件,这可能吗? 当然 - 插件可以做任何应用程序可以做的事情以及一些应用程序不能做的事情(或不能方便地做,例如 web.xml 编辑和自定义工件)。将 bean 注册放入插件描述符中的 doWithSpring 中,并使用与 resources.groovy 中相同的 bean builder 语法 好吧,似乎把那个类变成一个 bean 会改变我实例化它的方式。我已经在应用程序上运行了这个插件。如果可能的话,我想在不对该应用程序进行任何更改的情况下将其升级到 grails 2.4。我认为创建一个 grails 服务来实例化和初始化该类对于插件的未来版本可能是一个很大的改进,但是,现在,我只需要让东西工作。您知道如何静态访问该服务吗?

以上是关于从 Grails Holders 类中获取服务 bean的主要内容,如果未能解决你的问题,请参考以下文章

Grails:在普通的 groovy 类中获取数据源

Grails 覆盖插件服务静态方法

Grails 在服务类中获取会话和管理

在域类中使用 grails 服务

Grails Scaffolding Templates - 从域类中获取属性

如何在grails spring security自定义UserDetailsS​​ervices类中获取url参数?