2

Spring constructor injection of SLF4J logger - how to get injection target class?

I want to achieve similar functionality but in Spring boot.

I tried the solution given for this question but it seems postProcessBeanFactory method of BeanFactoryPostProcessor never gets invoked in my Spring-Boot application

Below is the implementation of method:

@SuppressWarnings("unused")
public class LoggerBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        String [] beanClasses = beanFactory.getBeanDefinitionNames();
        for(String beanName : beanClasses){
            Object beanObject = beanFactory.getBean(beanName);
            if(beanObject.getClass().isAnnotationPresent(Loggable.class)){
                try {
                    Field loggerField = beanObject.getClass().getDeclaredField("logger");
                    loggerField.setAccessible(true);
                    loggerField.set(beanObject, LoggerFactory.getLogger(beanObject.getClass()));
                }catch (NoSuchFieldException | IllegalAccessException e){
                    e.printStackTrace();
                }
            }
        }
    }
Community
  • 1
  • 1
Neeraj Jain
  • 7,643
  • 6
  • 34
  • 62

1 Answers1

4

Spring should know that you have added a new BeanFactoryPostProcessor, so you should declare this as a bean into your configuration. For xml config:

<bean class="your.package.LoggerBeanFactoryPostProcessor"  />

And for JavaConfig:

@Bean
public static BeanFactoryPostProcessor loggerBeanFactoryPostProcessor() {
    return new LoggerBeanFactoryPostProcessor();
}

Note: be sure to make a method in your JavaConfig that return BeanFactoryPostProcessor static. Without it will work fine until you want to use some other spring related features. For example using property @Value won't work.

From the documentation:

By marking this method as static, it can be invoked without causing instantiation of its declaring @Configuration class, thus avoiding the above-mentioned lifecycle conflicts. Note however that static @Bean methods will not be enhanced for scoping and AOP semantics as mentioned above. This works out in BFPP cases, as they are not typically referenced by other @Bean methods.

Sergii Bishyr
  • 8,331
  • 6
  • 40
  • 69
  • the XML method BeanFactoryPostProcessor is not called when I use XmlBeanDefinitionReader with DefaultListableBeanFactory, and I can not figure out why? – Yu Jiaao Feb 06 '18 at 06:55
  • @YuJiaao maybe post a separate question with the code example and all the details? – Sergii Bishyr Feb 06 '18 at 08:45
  • I post a new question and an example on `github`, https://stackoverflow.com/questions/48640952/how-to-call-beanfactorypostprocessor-postprocessbeanfactory-method-when-use-spri – Yu Jiaao Feb 06 '18 at 10:40