@PostConstruct 在 Grails 服务上静默失败

Posted

技术标签:

【中文标题】@PostConstruct 在 Grails 服务上静默失败【英文标题】:@PostConstruct fails silently on a Grails Service 【发布时间】:2013-01-27 17:26:58 【问题描述】:

我认为 Spring 注释应该在 Grails 环境中开箱即用,但我根本无法让它工作。我也尝试了 afterProperties 方法,但也没有用。

谁能发现错误?我需要做一些配置吗?

package dashboard

import javax.annotation.PostConstruct

class EmailJobSchedulerService

    def grailsApplication

    @PostConstruct
    def init() 
        def cronExpression = grailsApplication.config.emailAt8AmTrigger
        println(cronExpression)
        EmailSubscribersJob.schedule(cronExpression, new HashMap())
    

【问题讨论】:

该注释设置了很多约束(请参阅docs.oracle.com/javase/7/docs/api/javax/annotation/…)。它们都适用吗? @lucke84 根据 Ian 的建议将其更改为 void 后,我应该遵守所有约束 您希望何时打印 cronExpression?在服务器启动?我相信这是在第一次调用任何服务方法时调用的,而不是在服务器启动时调用的。我建议在引导程序中调用一个虚拟方法来确认。 @uchamp 我希望在 Spring 完成配置我的 bean 时调用它 【参考方案1】:

试试改成

@PostConstruct
void init() 

(即void 而不是def)。我不确定 Spring 是否专门强制执行此操作,但 specification of @PostConstruct 指出“方法的返回类型必须为 void”。

编辑:uchamp 的评论是正确的,我只是尝试了相同的测试,实际上 @PostConstruct 注释方法仅在第一次使用服务 bean 时调用,不一定在启动时立即调用。你可以添加

static lazyInit = false

到服务类以强制它在启动时急切地初始化。这似乎没有记录在用户指南中,我是通过reading the code 推断出来的。

请注意,上一段中的“使用”并不一定意味着您必须在其上调用方法。服务 bean 将在第一次从应用程序上下文中获取时被初始化,无论是直接还是因为它已自动装配到另一个正在初始化的 bean 中。例如,使用

将服务注入BootStrap
def emailJobSchedulerService

足以触发@PostConstruct 方法,您不必从BootStrap.init 闭包中实际调用任何服务方法。同样,如果您的服务被注入任何控制器,那么 init 将在其中一个控制器第一次处理请求时触发(任何请求,它不必是调用服务的操作)。

【讨论】:

还是什么都没有。不过感谢您的努力:) @willcodejavaforfood 假设有问题的.groovy 文件位于grails-app/services 而不是src/groovy,那么它应该正常工作。我多次使用相同的技巧。不过要注意的一件事是 GORM 在@PostConstruct 时间可能不可用。如果您需要对 GORM 方法做任何事情,您可能必须定义一个普通的非注释方法并从 BootStrap 中调用它。 这很奇怪。甚至只使用命令行创建了一个全新的项目,也没有在那里调用@PostConstruct。我不需要为此使用 GORM,只需安排我没有持久化的作业。 @willcodejavaforfood 经过一番挖掘后,看起来 static lazyInit = false 就是您要找的东西。 太棒了!不知道这个选项。【参考方案2】:

只是添加来自@Ian 的答案 - 出于某种原因,我有:

@PostConstruct
private void init() 

这也默默地失败并给出了奇怪的行为。解决方案是删除“私人”:

@PostConstruct
void init() 

【讨论】:

以上是关于@PostConstruct 在 Grails 服务上静默失败的主要内容,如果未能解决你的问题,请参考以下文章

@PostConstruct注解

为啥使用@PostConstruct?

@PostConstruct方法的使用以及原理,@Component+@PostConstruct方法将一个方法完成初始化操作

@PostConstruct注解小结

@PostConstruct 注解

PostConstruct