Search code examples
springdependency-injectionjava-ee-6cdiproducer

What is the Spring DI equivalent of CDI's InjectionPoint?


I would like to create a Spring's bean producer method which is aware who invoked it, so I've started with the following code:

@Configuration
public class LoggerProvider {

    @Bean
    @Scope("prototype")
    public Logger produceLogger() {
        // get known WHAT bean/component invoked this producer 
        Class<?> clazz = ...

        return LoggerFactory.getLogger(clazz);
    }
}

How can I get the information who wants to get the bean injected?

I'm looking for some equivalent of CDI's InjectionPoint in Spring world.


Solution

  • As far as I know, Spring does not have such a concept.

    Then only thing that is aware of the point that is processed is a BeanPostProcessor.


    Example:

    @Target(PARAMETER)
    @Retention(RUNTIME)
    @Documented
    public @interface Logger {}
    
    public class LoggerInjectBeanPostProcessor implements BeanPostProcessor {   
        public Logger produceLogger() {
            // get known WHAT bean/component invoked this producer
            Class<?> clazz = ...    
            return LoggerFactory.getLogger(clazz);
        }
    
    
        @Override
        public Object postProcessBeforeInitialization(final Object bean,
                final String beanName) throws BeansException {
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(final Object bean,
                final String beanName) throws BeansException {
    
            ReflectionUtils.doWithFields(bean.getClass(),
                    new FieldCallback() {
                         @Override
                         public void doWith(final Field field) throws IllegalArgumentException, IllegalAccessException {
                             field.set(bean, produceLogger());
                         }
                    },
                    new ReflectionUtils.FieldFilter() {
                         @Override
                         public boolean matches(final Field field) {
                              return field.getAnnotation(Logger.class) != null;
                         }
                    });
    
            return bean;
        }
    }