Spring beans decoration provided by Grails

I know that I can replace the Spring bean provided by Grails simply by defining my own bean with the same name. For example, if I want to replace the messageSourcebean provided by Grails

class MyMessageSource implements MessageSource {
    // methods omitted
}

Then add the following to resources.groovy

messageSource(MyMessageSource)

However, suppose I want to MyMessageSourcebeautify the implementation of this bean provided by Grails

class MyMessageSource implements MessageSource {

    // this field should be set to the MessageSource impl provided by Grails
    MessageSource messageSource
}

I can’t figure out how to do this resources.groovy. Obviously, I cannot do this:

messageSource(MyMessageSource) {
    messageSource = ref('messageSource')
}

Because it looks like I'm defining a bean that depends on itself. I could, of course, give my bean a different name, for example.

myMessageSource(MyMessageSource) {
    messageSource = ref('messageSource')
}

But then any class outside my control (for example, the plugin class) declaring a dependency on messageSourcewill be set to the bean provided by Grails, and not my decorator.

+4
2

( ) - ...

:

// 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
}
+7

messageSource bean, bean, messageSource bean, bean "messageSource", DI, bean bean, . doWithApplicationContext ( doWithSpring).

+1

Source: https://habr.com/ru/post/1539782/


All Articles