CDI1.1にて@SessionscopedなBeanをServletやServletFilterにInjectした場合
スレッドセーフに扱えますか。(Httpセッションは共有して)
情報ソースや検証方法として良い方法もあれば教えていただきたいです。
<環境>
- JavaEE7 (CDI 1.1)
- Glassfish 4.1
- JDK 1.8
以下のようにServletやServletFilterに@SessionScopedなBeanをInjectした場合、
スレッドごとに適切なBeanがCDIから提供されるのでしょうか。
CDI仕様(JSR346)や書籍、Web情報を確認して自分なりに理解したこととしては以下です。
- ServletやServletFilterはアプリケーション内で1つのインスタンスをマルチスレッドで利用される
- CDIにてInjectされるインスタンスは実際のクラスを継承した動的なクライアントプロキシインスタンス
- クライアントプロキシ経由で実際のインスタンスにアクセスすることでスレッドごとに適切なインスタンスをCDIが提供してくれる(->スレッドセーフになる?)
Java
1 2/** 3 * SessionScopedなBean 4 */ 5@Named 6@SessionScoped 7class MySessionBean implements Serializable { 8 private String id; 9 private String name; 10 // 以下アクセサ 11 ... 12} 13 14/** 15 * Servlet 16 */ 17@WebServlet(name = "hogeServlet", urlPatterns = {"/hoge/*"}) 18class HogeServlet extends HttpServlet { 19 20 // SessionBean 21 @Inject 22 private MySessionBean sessionBean; 23 24 @Override 25 protected void doGet(HttpServletRequest req, HttpServletResponse res) 26 throws ServletException, IOException { 27 // 他の処理でsessionBeanに情報がセットされているとする 28 29 // セッション情報の参照 30 System.out.println("sessionBean.id: " + sessionBean.getId()); 31 System.out.println("sessionBean.name: " + sessionBean.getName()); 32 33 // 以下、何か処理 34 ... 35 } 36} 37 38/** 39 * Servlet Filter 40 * web.xmlにfilter定義、mapping定義をする 41 */ 42class HogeFilter implements Filter { 43 44 // SessionBean 45 @Inject 46 private MySessionBean sessionBean; 47 48 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 49 throws IOException, ServletException { 50 51 // セッション情報設定 52 sessionBean.setId("hogehoge0001"); // 実際にはrequestのQueryStringから値を設定 53 sessionBean.setName("hoge太郎"); // 実際にはrequestのQueryStringから値を設定 54 55 // chain 56 chain.doFilter(request, response); 57 58 // セッション情報参照 59 System.out.println("sessionId: " + request.getSession().getId()); 60 System.out.println("sessionBean.id: " + sessionBean.getId()); 61 System.out.println("sessionBean.name: " + sessionBean.getName()); 62 } 63 64 // 以下、必要なメソッドを実装 65 .... 66} 67
上記のようなコードを利用して、2つのブラウザから同時アクセスして
(HogeServlet#doGet()に時間のかかる処理を実装して同時アクセスできるようにして)
動作検証しました。
以下のような結果となったため、うまく動作しているようでしたが技術的に理解できていません。
- ブラウザAでクエリセット(GETパラメータ)した値がセッションIDとともに正しくコンソール出力される
- ブラウザBでクエリセット(GETパラメータ)した値がセッションIDとともに正しくコンソール出力される
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。