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 路径可能为时已晚,您可能需要更多代码来完成此操作。