Spring在运行时添加bean

时间:2015-12-04 17:42:10

标签: spring spring-integration

我正试图想出一种在应用程序启动后动态添加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后未触发的后处理器。我不能在这里强行刷新。

有没有办法解决这个鸡蛋问题?

1 个答案:

答案 0 :(得分:2)

请参阅AutowireCapableBeanFactory.initializeBean(beanName)

您需要确保在注册和初始化之间没有使用bean。

另外,请注意,在初始化上下文之后注册单例并非直到最近都是线程安全的(我认为是4.2.2)。如果其他代码在工厂中遍历bean,则可能导致ConcurrentModificationExceptions

但是,在这种情况下,注册HTTP路径可能为时已晚,您可能需要更多代码来执行此操作。