实例列表表现为全局列表

时间:2015-12-03 18:36:59

标签: java spring

我有一个发布订阅队列消息侦听器方法,当它在队列中读取消息时触发事件。将消息添加到ApplicationListener类中的publisherPostListenerList

列表中添加的消息正被推送到多个订阅者,例如来自控制器方法的实时通知。

将消息推送到相应的登录用户后,我将从列表中删除消息,以避免将冗余消息推送给用户,同时还会检查列表的大小。

问题是所有登录用户只有publisherPostListenerList的单个实例。作为实例列表的列表应该为每个登录用户提供单独的副本,但事实并非如此。如果我错了,请纠正我。

如果我删除了一条消息,它会删除所有订阅者publisherPostListenerList的消息。

现在我的问题是

1 即可。不应该为每个登录用户提供publisherPostListenerList列表的单独副本,该列表是实例列表。

2. 如何为所有已登录的用户创建单独的列表副本

P.S。我尝试将bean范围更改为原型但不起作用。

下面是ApplicationEventListener类,它包含列表和列表。控制器代码。

ApplicationListener.java

@Component
public class ApplicationEventListener {

    private List<Post> publisherPostListenerList = new CopyOnWriteArrayList<Post>();

    private static final Logger logger = Logger.getLogger(ApplicationEventListener.class);

    @EventListener
    public void postSubmissionEventHandler(PostSubmissionEvent event) throws IOException {
        Post post = event.getPost();
        logger.debug("application published user post received " + post);
        publisherPostListenerList.add(post);
    }

    public List<Post> getPublisherPostListenerList() {
        return publisherPostListenerList;
    }

    public void setPublisherPostListenerList(List<Post> publisherPostListenerList) {
        this.publisherPostListenerList = publisherPostListenerList;
    }
}

将消息推送给订阅者的控制器方法

@RequestMapping(value="/getRealTimeServerPushUserPosts")
    public SseEmitter getRealTimeServerPushUserPosts(@RequestParam("userId") int userId){
        SseEmitter sseEmitter = new SseEmitter();
        CustomUserDetail myUserDetails = currentUserAccessor.getCurrentLoggedInUser();
        User loggedInUser=myUserDetails.getUser();

        List<Integer> userPublisherIDList = this.userService.loadUserPublisherIdListWhichLoggedInUserFollows(loggedInUser);
        List<Post> postList =eventListener.getPublisherPostListenerList();


        for(Integer userPublisherId : userPublisherIDList){
            for(Post post:postList){
                    if((userPublisherId.intValue()) == (post.getUser().getUserId().intValue())){
                        try {
                        sseEmitter.send(post);
                        postList.remove(post); //removes the post for all the subscribers as the list acts as a global list.
                    } catch (IOException e) {
                        logger.error(e);
                    }
                }
             }
         }
        return sseEmitter;
    }

0 个答案:

没有答案