装饰由Grails提供的Spring bean

Dón*_*nal 4 grails spring

我知道我可以通过定义具有相同名称的自己的bean来替换Grails提供的Spring bean.例如,如果我想替换messageSourceGrails提供的bean

class MyMessageSource implements MessageSource {
    // methods omitted
}
Run Code Online (Sandbox Code Playgroud)

然后添加以下内容 resources.groovy

messageSource(MyMessageSource)
Run Code Online (Sandbox Code Playgroud)

但是,假设我想MyMessageSource装饰Grails提供的这个bean的实现

class MyMessageSource implements MessageSource {

    // this field should be set to the MessageSource impl provided by Grails
    MessageSource messageSource
}
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚如何连接它resources.groovy.显然我不能这样做:

messageSource(MyMessageSource) {
    messageSource = ref('messageSource')
}
Run Code Online (Sandbox Code Playgroud)

因为看起来我正在定义一个依赖于它自己的bean.我当然可以给我的豆子命名,例如

myMessageSource(MyMessageSource) {
    messageSource = ref('messageSource')
}
Run Code Online (Sandbox Code Playgroud)

但是,任何超出我控制范围的类(例如插件类)都声明依赖,messageSource将被设置为Grails而不是我的装饰器提供的bean.

Jef*_*own 7

在一个应用程序(不是一个插件)中,沿着这些行的东西应该工作......

新消息来源:

// src/groovy/com/demo/MyMessageSource.groovy
package com.demo

import org.springframework.context.MessageSource
import org.springframework.context.MessageSourceResolvable
import org.springframework.context.NoSuchMessageException

class MyMessageSource implements MessageSource {
    MessageSource theRealMessageSource

    String getMessage(String code, Object[] args, String defaultMessage, Locale locale) {
        theRealMessageSource.getMessage code, args, defaultMessage, locale
    }

    String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException {
        theRealMessageSource.getMessage code, args, locale
    }

    String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
        theRealMessageSource.getMessage resolvable, locale
    }
}
Run Code Online (Sandbox Code Playgroud)

后处理器:

// src/groovy/com/demo/MyPostProcessor.groovy
package com.demo

import org.springframework.beans.factory.config.BeanFactoryPostProcessor
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory
import org.springframework.beans.BeansException

class MyPostProcessor implements BeanFactoryPostProcessor {

    @Override
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        // error handling ommitted for brevity here...

        def realMessageSource = beanFactory.getBean('messageSource')
        def newMessageSource = new MyMessageSource()
        newMessageSource.theRealMessageSource = realMessageSource

        beanFactory.removeBeanDefinition 'messageSource'
        beanFactory.registerSingleton 'messageSource', newMessageSource
    }
}
Run Code Online (Sandbox Code Playgroud)

注册后处理器:

// grails-app/conf/spring/resources.groovy
beans = {
    myMessageSourcePostProcessor com.demo.MyPostProcessor
}
Run Code Online (Sandbox Code Playgroud)