Grails 4.0.1 - MessageSource 注入和使用方法 get Message 给出空指针异常错误

Grails 4.0.1 - MessageSource injection and using method get Message giving null pointer exception error

我正在升级到 Grails 4.0.1,我遇到了国际化问题。我不断收到 NullPointerException 错误 java.lang.NullPointerException: Cannot invoke method getMessage() on null object。导致错误的代码行是:

  return messageSource.getMessage('dashboard.completed.label', 'Approved', LocaleContextHolder.getLocale())

当我println(messageSource)时,值为null。我试过添加

   spring: 
       messages:
           basename: grails-app/i8n/** 

我的 application.yml,但我仍然遇到同样的错误。我想也许问题是我的 resources.groovy 中缺少一个 bean,所以我将以下 messageSource bean 添加到 resources.groovy:

   beans = {
        messageSource(ReloadableResourceBundleMessageSource){
            basename = grails-app/i18n/messages
        }
   }

但是,这会产生以下错误 org.grails.core.exceptions.GrailsConfigurationException: Error loading spring/resources.groovy file: No such property: grails for class: grails.spring.BeanBuilder

然后我决定尝试将 bean 放在 resources.xml 文件中而不是 resources.groovy

  <bean id="messageSource"
     class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
     <property name="basename" value="grails-app/i18n/" />
     <property name="defaultEncoding" value="UTF-8" />
 </bean>

但这也会产生 NullPointerException。在搜索互联网后,我发现了一个资源,该资源建议通过在 bootstrap.groovy 中初始化 messageSource 来解决此问题,因此我向其中添加了以下内容:

  def messageSource

  def init = { servletContext ->
       messageSource.basenames = ['/grails-app/i18n/messages']
       messageSource.afterPropertiesSet()
  } 

这会产生相同的 NullPointerException 错误。

这在我升级之前工作正常。如果我从 bootstrap.groovy 内部 println(messageSource),程序会打印基名数组。但是,在注入消息源后在我的控制器中执行 println(messageSource) 打印 "null"。也许我在升级过程中遗漏了什么,但我不确定是什么。有谁知道为什么我会收到错误以及我可以采取哪些可能的步骤来修复它?

https://github.com/jeffbrown/rookiecodermessagesource 查看项目。

https://github.com/jeffbrown/rookiecodermessagesource/blob/78d8760cd057b8eda25f72ddca05390463cbb68b/grails-app/init/rookiecodermessagesource/BootStrap.groovy

package rookiecodermessagesource

class BootStrap {
    def messageSource

    def init = { servletContext ->
        println messageSource
    }
    def destroy = {
    }
}

效果很好,应该如此。

在控制器或服务导入中:

import org.springframework.context.MessageSource
import org.springframework.context.i18n.LocaleContextHolder

然后声明:

@Autowired
private MessageSource messageSource

并像这样使用:

messageSource.getMessage('my.message.properties.msg', null, 'Default Message', LocaleContextHolder.locale)

它适用于 Grails 4.0.1