Программное добавление 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;
}