使用Spring集成实现消费者和生产者系统

时间:2014-04-04 12:08:56

标签: spring spring-integration

我想使用Spring SubscribableChannel实现单个生产者..多个消费者问题。我无法解决这个问题。

例如,我有一个用户作为制作人,他的朋友作为消费者。因此,当制作人用户做某事时,必须将其发布给他的朋友。

真正的问题是生产者和消费者的关系是动态的,因为在任何时候我都可以与用户取消联系,这意味着它不应该再听我的活动了。所以我想要一些java配置,我可以订阅和取消订阅生产者的消费者,如果生产者不再存在,必须有一些东西可以将消费者与生产者分离......

我在设计频道时遇到困难,因为会有number of channel equal to number of users.我也不确定如何设计Spring Integration附带的MessageHandler。

是否有一些指向这个方向的例子。

我到目前为止所做的是我有一个配置bean

@Configuration
public class ChannelConfig {

    @Bean
    public SubscribableChannel subscribeChannel() {
        PublishSubscribeChannel channel = new PublishSubscribeChannel(getAsyncExecutor());
        return channel;
    }

    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(50);
        executor.setQueueCapacity(10000);
        executor.setThreadNamePrefix("ChannelExecutor-");
        executor.initialize();
        return executor;
    }
}

我将注入,但这将是唯一的唯一渠道。我希望每个用户都有一个频道。

2 个答案:

答案 0 :(得分:0)

为什么要为每个用户设置单独的频道?这就是发布/子频道的重点;对于该频道的每个用户,只需subscribe()一个新的MessageHandler。然后,发送到该频道的任何消息都将被发送给每个消费者。

编辑:(基于下面的评论)。

在这种情况下,不是将通道声明为@Bean,而是简单地以编程方式将其实例化(或者将其范围设置为prototype并为每个生产者获取一个新实例)并订阅他的“朋友”。

答案 1 :(得分:0)

我正在做这样的事情

public class ChannelCreator {

    private Map<String , SubscribableChannel> channels;
    ThreadPoolTaskExecutor executor;

    public ChannelCreator() {
        channels = new ConcurrentHashMap<String, SubscribableChannel>();
        prepareAsyncExecutor();
    }

    public void createChannel(String login) {
        PublishSubscribeChannel channel = new PublishSubscribeChannel(executor);
        channels.put(login, channel);
    }

    public SubscribableChannel getChannel(String login){
        SubscribableChannel channel = channels.get(login);
        if(channel == null){
            channel = new PublishSubscribeChannel(executor);
            channels.put(login, channel);
        }
        return channel;
    }

    public void removeChannel(String login){
        channels.remove(login);
    }

    public Executor prepareAsyncExecutor() {
        executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(2);
        executor.setMaxPoolSize(50);
        executor.setQueueCapacity(10000);
        executor.setThreadNamePrefix("ChannelExecutor-");
        executor.initialize();
        return executor;
    }
}

@Configuration
public class ChannelConfig {

    @Bean
    public ChannelCreator channelCreator() {
        ChannelCreator creator = new ChannelCreator();
        return creator;
    }
}