Spring 在运行时添加 bean
Spring adding beans at runtime
我正在尝试想出一种在应用程序启动后动态添加 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 依赖于 post 处理器,该处理器在注册单例 bean 后未被触发。我真的不能在这里强制刷新。
有办法解决这个先有鸡还是先有蛋的问题吗?
参见AutowireCapableBeanFactory.initializeBean(beanName)。
您需要确保在注册和初始化之间未使用该 bean。
另外,请注意,在初始化上下文之后注册单例直到最近(我认为是 4.2.2)才真正是线程安全的。如果其他代码正在工厂中的 bean 上迭代,它可能会导致 ConcurrentModificationExceptions
。
但是,在这种情况下,注册 HTTP 路径可能为时已晚,您可能需要更多代码来完成此操作。
我正在尝试想出一种在应用程序启动后动态添加 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 依赖于 post 处理器,该处理器在注册单例 bean 后未被触发。我真的不能在这里强制刷新。
有办法解决这个先有鸡还是先有蛋的问题吗?
参见AutowireCapableBeanFactory.initializeBean(beanName)。
您需要确保在注册和初始化之间未使用该 bean。
另外,请注意,在初始化上下文之后注册单例直到最近(我认为是 4.2.2)才真正是线程安全的。如果其他代码正在工厂中的 bean 上迭代,它可能会导致 ConcurrentModificationExceptions
。
但是,在这种情况下,注册 HTTP 路径可能为时已晚,您可能需要更多代码来完成此操作。