程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA編程入門知識 >> Spring Singleton的陷阱

Spring Singleton的陷阱

編輯:JAVA編程入門知識

  這是一個真實的案例,我們在項目中使用Spring和ACEGI,我之所以選擇ACEGI,除了它對權限的良好控制外,

  我還看好它的SecurityContextHolder,通過代碼

  Authentication auth = SecurityContextHolder.getContext().getAuthentication();

  我可以很容易在系統任意一層得到用戶的信息,而不用把用戶信息在參數裡傳來傳去,(這也是struts的缺點之一)

  但是我在每一次要得到用戶信息的時候都寫上面的一段代碼,未免有些麻煩,所以我在BaseService, BaseDao裡都提供了如下方法:

  /**//**
   * get current login user info
   * @return UserInfo
   */
  protected UserInfo getUserInfo()
  ...{
      return getUserContext().getUserInfo();
  }

  /**//**
   * get current login user context
   * @return UserContext
   */
  protected UserContext getUserContext()
  ...{
      Authentication auth = SecurityContextHolder.getContext().getAuthentication();
      return (UserContext) auth.getPrincipal();
  }  

  這樣在其他的Service和Dao類裡可以通過

  super.getUserContext(), super.getUserInfo()  

  來得到用戶的信息,這也為問題的產生提供了溫床。請看如下代碼:

  public class SomeServece extends BaseService implements SomeInterFace
  ...{
      private UserInfo user = super.getUserInfo();

      public someMethod()
      ...{
         int userID = this.user.getUserID();
         String userName = this.user.getUserName();
         //bla bla do something user userID and userNaem  
      }
  }      

  這段代碼在單元測試的時候不會用任何問題,但是在多用戶測試的情況下,你會發現任何調用SomeService裡someMethod()方法的userID和userName都是同一個人,也就是第一個登陸的人的信息。Why?
  其根本原因是Spring的Bean在默認情況下是Singleton的,Bean SomeServece的實例只會生成一份,也就是所SomeServece實例的user 對象只會被初始化一次,就是第一次登陸人的信息,以後不會變了。所以BaseService想為開發提供方便,確給開發帶來了風險正確的用法應該是這樣的

  public class SomeServece extends BaseService implements SomeInterFace
  ...{

  
      public someMethod()
      ...{
         int userID = super.getUserInfo().getUserID();
         String userName = super.getUserInfo().getUserName();
         //bla bla do something user userID and userNaem  
      }
  }

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved