@Stateful
最終的に、 Beanの参照を取得できる回避策を見つけました。
Beanの参照を@Named @Singleton @Startup
持つローカルを保持する Bean SessionControllerを作成しました。HashMap<String, UserSession> sessionMap
@Stateful
@Named
@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.CONTAINER)
public class SessionController {
private HashMap<String, UserSession> sessionMap;
@PostConstruct
void init() {
sessionMap = new HashMap<String, UserSession>();
}
@PreDestroy
void terminate() {
for (UserSession us : sessionMap.values()) {
us.logoutCleanUp(); //This is annotated as @Remove
}
sessionMap.clear();
}
public void addSession(String sessionId, UserSession us) {
sessionMap.put(sessionId, us);
System.out.println("New Session added: " + sessionId);
}
public UserSession getCurrentUserSession() {
FacesContext context = FacesContext.getCurrentInstance();
String sessionId = ((HttpSession) context.getExternalContext().getSession(false)).getId();
return sessionMap.get(sessionId);
}
}
各 Bean の@PostConstruct
メソッド内から参照を追加します。
public class UserSession implements Serializable {
@Inject SessionController sc;
...
@PostConstruct
void init() {
FacesContext context = FacesContext.getCurrentInstance();
String sessionId = ((HttpSession) context.getExternalContext().getSession(true)).getId();
sc.addSession(sessionId, this);
}
.getSession(true)
セッションがまだ作成されていない可能性があるため、これが必要であることに注意してください。はコンストラクタではないthis
ため、安全に渡されることにも注意してください...@PostConstruct
これらすべての後、次のように EntityListener (およびその他の場所) で参照を取得できます。
SessionController sc = (SessionController) new InitialContext().lookup("java:module/SessionController");
UserSession us = sc.getCurrentUserSession();
またはCDI Beanでこのように
@Inject SessionController sc;
FacesContext context = FacesContext.getCurrentInstance()
私が見る唯一の欠点は、このアプローチが Web アプリケーション (意味のある場所) でのみうまく機能することです。一部の Bean (および最終的には EntityListeners) も@javax.jws.WebService
as @Stateless
Bean を介して公開されます。このコンテキスト (実際には: が存在しない) では、いかなる種類のsessionIdも存在しないため (正確にはセッションがまったく存在しないため)、私のシングルトンは機能しません (まだテストしていません)。おそらくBeanのSessionContextを使用するか、何らかの使用可能なsessionIdを発明することで、これを回避する必要があります。使いやすいものを作成したら投稿します...