Java 跨所有会话的应用程序范围bean?

Java 跨所有会话的应用程序范围bean?,java,jsf,Java,Jsf,希望我能有点道理,我以前从未做过这个特殊的任务 我有一个应用程序,我想在启动时创建一个bean,它有一个每30分钟运行一次的计划任务,并更新应用程序中所有会话使用的映射。我最初的想法是为这个任务创建一个应用程序范围的bean 所以这个想法是: 用户A登录。在他的地图上存储价值 用户B登录。在他的地图上存储价值 进程运行,更新映射中的所有值 用户B和A将在整个会话期间不断检查其值 注销,从映射中删除值 所以现在看起来是这样的: @ManagedBean(eager=true, name="moni

希望我能有点道理,我以前从未做过这个特殊的任务

我有一个应用程序,我想在启动时创建一个bean,它有一个每30分钟运行一次的计划任务,并更新应用程序中所有会话使用的映射。我最初的想法是为这个任务创建一个应用程序范围的bean

所以这个想法是:

  • 用户A登录。在他的地图上存储价值
  • 用户B登录。在他的地图上存储价值
  • 进程运行,更新映射中的所有值
  • 用户B和A将在整个会话期间不断检查其值
  • 注销,从映射中删除值
  • 所以现在看起来是这样的:

    @ManagedBean(eager=true, name="monitor")
    @ApplicationScoped
    public class MyMonitor implements Serializable {
    
        private static final long serialVersionUID = -1L;
        private ScheduledExecutorService scheduler; 
        private HashMap<Integer, String> myDict;
    
        @PostConstruct
        public void init() {
            myDict = new HashMap<Integer, String>();
            myDict.put(1, "a");
            myDict.put(2, "b");
            myDict.put(3, "c");
    
            scheduler = Executors.newSingleThreadScheduledExecutor();
            scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 30, TimeUnit.SECONDS);
        }
    
        @PreDestroy
        public void destroy() {
            scheduler.shutdownNow();
        }
    
        public class SomeDailyJob implements Runnable {
    
            @Override
            public void run() {
                System.out.println("hello world");
            }
    
        }
    
        public HashMap<Integer, String> getMyDict() {
            return myDict;
        }
        public void setMyDict(HashMap<Integer, String> myDict) {
            this.myDict = myDict;
        }
    }
    
    得到:

    WARNING: The web application [app] is still processing a request that has yet to finish
    
    我的问题是:

  • 我真的应该使用ApplicationScoped bean来解决这个问题吗? 我没有EJB
  • 我知道我还没有添加同步性, 但这安全吗?这真的有效吗

  • 您可以使用java.util.Timer进行此操作。定义一个类

        import java.util.TimerTask;
    
        public class Monitor extends TimerTask {
    
            @Override
            public void run() {
              // do something
            }
        }
    
    然后你的类可能会被重构成类似这样的东西(我删除了其他代码以保留这个想法)


    这也将帮助您移动
    Monitor.run()
    中的大部分更新逻辑,将其与调度程序逻辑分离。我希望这能有所帮助。

    所以你找到了BalusC的答案,但决定不让weblistener管理日程安排?根据您的观点,您永远不应该使用java EEOP中的java.util.Timer,否则EJB将是可用的
        import java.util.TimerTask;
    
        public class Monitor extends TimerTask {
    
            @Override
            public void run() {
              // do something
            }
        }
    
    @ManagedBean(eager=true, name="monitor")
    @ApplicationScoped
    public class MyMonitor implements Serializable {
    
        //runs as daemon thread
        private final Timer timer = new Timer(true);
        private Monitor monitor = new Monitor();
    
        @PostConstruct
        public void init() {       
           // period are in milliseconds
           timer.scheduleAtFixedRate(monitor, 0, 30*1000);
        }
    
        @PreDestroy
        public void destroy() {
           timer.cancel();
        }
    }