java应用程序跨所有会话处理bean?
希望我能有点道理,我以前从未做过这个特殊的任务
我有一个应用程序,我想在启动时创建一个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;
}
}
在另一个类中,我需要基于key从myDict检索值(这个类位于DAO层,它不是托管bean)。我尝试在该类中实例化此bean:
public class MyDAO {
@ManagedProperty(value="#{myMonitor}")
private MyMonitor monitor;
}
得到:
WARNING: The web application [app] is still processing a request that has yet to finish
我的问题是:
- 我真的应该使用ApplicationScoped bean来解决这个问题吗? 我没有EJB李>
- 我知道我还没有添加同步性, 但这安全吗?这真的有效吗李>
# 1 楼答案
您可以使用java。util。这个计时器。定义一个类
然后你的类可能会被重构成类似这样的东西(我删除了其他代码以保留这个想法)
这也将帮助您移动
Monitor.run()
中的大部分更新逻辑,将其与调度程序逻辑分离。我希望有帮助