我正试图想出一种在应用程序启动后动态添加spring bean的方法。
我发现了几个有类似问题的地方,例如here
我知道ApplicationContext扩展点,例如ApplicationContext事件和BeanFactoryPostProcessor。
我手头的问题是我需要在创建一些bean之后添加bean,我想这会抛弃BeanFactoryPostProcessor选项,因为它会在应用程序上下文开始注册bean之前发生。
我尝试在刷新上下文后添加singletonBean:
@EventListener
public void postProcess(ContextRefreshedEvent refreshedEvent) throws BeansException {
ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext)refreshedEvent.getApplicationContext()).getBeanFactory();
List<Api> apis = repository.findAll();
apis.forEach(api -> {
api.getEndpoints().forEach(endpoint -> {
HttpRequestHandlingMessagingGateway gateway = createGateway(endpoint);
customIntegrationHandlerMapping.register(gateway);
beanFactory.registerSingleton("httpflow-"+endpoint.getId(),createEndpointFlow(gateway));
});
});
}
问题在于IntegrationFlow依赖于注册单例bean后未触发的后处理器。我不能在这里强行刷新。
有没有办法解决这个鸡蛋问题?
答案 0 :(得分:2)
请参阅AutowireCapableBeanFactory.initializeBean(beanName)。
您需要确保在注册和初始化之间没有使用bean。
另外,请注意,在初始化上下文之后注册单例并非直到最近都是线程安全的(我认为是4.2.2)。如果其他代码在工厂中遍历bean,则可能导致ConcurrentModificationExceptions
。
但是,在这种情况下,注册HTTP路径可能为时已晚,您可能需要更多代码来执行此操作。