@PostConstruct在Grails服务上静默失败

wil*_*ood 8 grails spring annotations postconstruct

我认为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())
    }
}
Run Code Online (Sandbox Code Playgroud)

Ian*_*rts 16

尝试将其更改为

@PostConstruct
void init() {
Run Code Online (Sandbox Code Playgroud)

(即void代替def).我不确定Spring是否特别强制执行此操作,但是规范@PostConstruct状态除其他外"方法的返回类型必须是无效的".

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

static lazyInit = false
Run Code Online (Sandbox Code Playgroud)

到服务类强制它在启动时急切地初始化.这似乎没有在用户指南中记录,我通过阅读代码推断出它.

请注意,前一段中的"used"并不一定意味着您必须在其上调用方法.服务bean将在第一次从应用程序上下文中直接获取时初始化,或者因为它已被自动连接到另一个正在初始化的bean中.例如,使用将服务注入BootStrap

def emailJobSchedulerService
Run Code Online (Sandbox Code Playgroud)

足以启动该@PostConstruct方法,您不必从BootStrap.init闭包中实际调用任何服务的方法.类似地,如果您的服务被注入到任何控制器中,则init会在其中一个控制器第一次处理请求时触发(任何请求,它不必是调用服务的操作).

  • @willcodejavaforfood 假设有问题的“.groovy”文件位于“grails-app/services”而不是“src/groovy”中,那么它应该可以正常工作。我已经多次使用过同样的技巧。但需要注意的一件事是 GORM 可能在“@PostConstruct”时间不可用。如果您需要使用 GORM 方法执行任何操作,您可能必须定义一个普通的无注释方法并从 BootStrap 调用它。 (2认同)