Программное добавление Beans в контекст приложения Spring

Я пытаюсь добавить простую строку в мой контекст приложения Spring, а затем автоматически связать ее с другим существующим компонентом (A) в контексте приложения. Я знаю, что это не обычный путь, но мне нужно программно добавить много bean-компонентов, что в противном случае увеличило бы мою конфигурацию xml.

public class MyPostProcessor implements BeanFactoryPostProcessor, Ordered {

  @Override
  public int getOrder() {
    return 0;
  }

  @Override
  public void postProcessBeanFactory(
        ConfigurableListableBeanFactory beanFactory) throws BeansException {
    beanFactory.registerSingleton("myString", "this is the String");
    A a = beanFactory.getBean(A.class);
    beanFactory.autowireBean(a);
  }
}    

public class A {

    @Autowired 
    public transient String message;

}

При запуске этого свойства message экземпляра А является нулевым. Что мне не хватает?

РЕДАКТИРОВАТЬ: это мой контекст приложения:

@Configuration
class TestConfig {

  @Bean 
  public A a() {
    return new A();
  }

  @Bean
  public MyPostProcessor postProcessor() {
    return new MyPostProcessor();
  }

}

И это мой тест:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfig.class)
public class MyTest {

  @Autowired 
  private transient A a;

  @Test
  public void test() throws Exception {
    System.err.println("Running");
    System.err.println("This is the autowired String: " + a.message);
    Thread.sleep(1000);
  }

}

Спасибо

2 ответа

Решение

Вы не должны создавать бобы из BeanFactoryPostprocessors, От BeanFactoryPostProcessor JavaDoc:

BeanFactoryPostProcessor может взаимодействовать и изменять определения компонентов, но никогда не создавать экземпляры компонентов. Это может привести к преждевременной реализации бобов, нарушению контейнера и непреднамеренным побочным эффектам.

В вашем случае A боб создается раньше BeanPostProcessors и, следовательно, не с автоматической проводкой.

Удалить строки:

A a = beanFactory.getBean(A.class);
beanFactory.autowireBean(a);

И будет работать.

Попробуйте использовать @Qualifier к конкретному бобу, который вы хотите, чтобы Auto провод.

public class A {

    @Autowired 
    @Qualifier("myString")
    public transient String message;

}
Другие вопросы по тегам