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