我知道我可以通过定义自己的同名bean来替换Grails提供的Spring bean。例如,如果我想替换Grails提供的messageSource
bean
class MyMessageSource implements MessageSource {
// methods omitted
}
然后在resources.groovy
messageSource(MyMessageSource)
但是,假设我希望MyMessageSource
装饰Grails提供的这个bean的实现
class MyMessageSource implements MessageSource {
// this field should be set to the MessageSource impl provided by Grails
MessageSource messageSource
}
我无法弄清楚如何在resources.groovy
中进行连线。显然我不能这样做:
messageSource(MyMessageSource) {
messageSource = ref('messageSource')
}
因为我看起来像是在定义依赖于自身的bean。我当然可以给我的豆子命名,例如
myMessageSource(MyMessageSource) {
messageSource = ref('messageSource')
}
但是,任何超出我控制范围的类(例如插件类)声明对messageSource
的依赖都将被设置为Grails而不是我的装饰器提供的bean。
答案 0 :(得分: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
}
}
后处理器:
// 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
}
}
注册后处理器:
// grails-app/conf/spring/resources.groovy
beans = {
myMessageSourcePostProcessor com.demo.MyPostProcessor
}
答案 1 :(得分:1)
初始化上下文后,您可以检索messageSource bean,创建委托给messageSource bean的bean实例,然后使用名称" messageSource"中的上下文注册您的bean。所以当DI发生时,你的bean就是将被使用的bean。在插件中,您应该能够在doWithApplicationContext(而不是doWithSpring)中执行此操作。