Что является эквивалентом Spring DI InjectionPoint CDI? - PullRequest
13 голосов
/ 13 марта 2012

Я хотел бы создать метод производителя bean-компонентов Spring, который знает, кто его вызвал, поэтому я начал со следующего кода:

@Configuration
public class LoggerProvider {

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

        return LoggerFactory.getLogger(clazz);
    }
}

Как получить информацию who хочет ввести боб?

Я ищу какой-то эквивалент CDI InjectionPoint в мире Spring.

Ответы [ 2 ]

17 голосов
/ 11 июня 2016

Spring 4.3.0 включает параметры InjectionPoint и DependencyDescriptor для методов создания бинов:

@Configuration
public class LoggerProvider {

    @Bean
    @Scope("prototype")
    public Logger produceLogger(InjectionPoint injectionPoint) {
        Class<?> clazz = injectionPoint.getMember().getDeclaringClass();

        return LoggerFactory.getLogger(clazz);
    }
}

Кстати, проблема для этой функции SPR-14033 ссылается на комментарий к сообщению в блоге , который ссылается на этот вопрос.

6 голосов
/ 13 марта 2012

Насколько я знаю, Spring не имеет такой концепции.

Тогда единственное, что знает об обрабатываемой точке, это BeanPostProcessor .

* 1006.*

Пример:

@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;
    }
}
...