我们有CustomLoginModule
(扩展UsernamePasswordLoginModule
),可在登录时将所有用户和会话引用放入地图中。它们存储在@javax.enterprise.context.ApplicationScoped
bean中。
在注销时,会删除这些引用。要捕获意外注销,还可以从@PreDestroy
bean的javax.enterprise.context.SessionScoped
方法调用删除这些引用的方法。
当用户在两个位置登录时,第一个位置的会话无效,并且它的引用将从地图中删除。
这意味着当用户在第二个位置登录时,相应的记录将从地图中删除,然后@PreDestroy
方法会尝试再次删除它。
你会说,这不是一个大问题,我们只是从@PreDestroy
方法传递当前会话引用,并将其与地图中的会话进行比较,并且仅当两者相等时才删除会话。
但是,这就是我的问题,显然在会话注销时会调用NEW实例的@PreDestroy
方法。在调用@Predestroy
方法之后,同一个会话bean很快就会继续运行。
我对替代品并不感兴趣,因为有很多。我只是想知道这是如何可能的。
有问题的课程太复杂了,无法在此粘贴,但我试图表达他们的意图:
登录模块:
public class CustomLoginModule extends UsernamePasswordLoginModule {
login(){
SessionMap.addToMap(username, currentSession);
}
}
ApplicationScoped:
@ApplicationScoped
public class SessionMap{
addToMap(String username, HttpSession currentSession){
// get previously present session
previousSession.invalidate(); // this triggers the predestroy of the sessionscoped
// remove previous session from map
// put new session in map
}
}
SessionScoped:
@SessionScoped
public MySessionBean{
@PreDestroy
public void removeSession(){
// this predestroy is called after the session is invalidated in the addtomap method
// however, if you log the hash of this class, you will see that the second
// class's predestroy is called, not the first
SessionMap.removeFromMap(username, currentSession);
}
}