2012-12-20 88 views
1

春天bean的默認範圍是singleton。然而,當我已經定義下一個服務:春季的應用範圍

@Service("usersLoggedInService") 
public class UsersLoggedInServiceImpl implements UsersLoggedInService { 

private Map<Long, String> OnlineUsers = new LinkedHashMap<Long, String>(); 

@Override 
public Map<Long, String> getOnlineUsers() { 
    return OnlineUsers; 
} 

@Override 
public void setOnlineUsers(Long id, String username) { 
    OnlineUsers.put(id, username); 
} 

    @Override 
public void removeLoggedOutUser(Long id){ 
    if(!OnlineUsers.isEmpty() && OnlineUsers.size()>0) 
     OnlineUsers.remove(id); 
} 
} 

,並用它來登錄審覈所以每當新用戶登錄,我將它添加到OnlineUsers的LinkedHashMap在接下來的方式:在我服務的一個

usersLoggedInService.setOnlineUsers(user.getId(), user.getUsername()); 

類。這工作正常,我可以看到在地圖中添加的用戶。

但是,在註銷時,我想要刪除在LinkedhashMap中添加的用戶,並且當我檢查usersLoggedInService.getOnlineUsers()時,我可以看到它是空的。我不明白爲什麼。

註銷處理程序定義:

<logout invalidate-session="true" 
     logout-url="/logout.htm" 
     success-handler-ref="myLogoutHandler"/> 

及其實施:

@Component 
public class MyLogoutHandler extends SimpleUrlLogoutSuccessHandler { 

@Resource(name = "usersLoggedInService") 
UsersLoggedInService usersLoggedInService; 

@Override 
public void onLogoutSuccess(HttpServletRequest request, 
     HttpServletResponse response, Authentication authentication) 
     throws IOException, ServletException { 
    if (authentication != null) { 
     Object principal = authentication.getPrincipal(); 
      if(principal instanceof User){ 
       User user = (User) principal; 
       usersLoggedInService.removeLoggedOutUser(user.getId());  

      } 


    } 
    setDefaultTargetUrl("/login"); 
    super.onLogoutSuccess(request, response, authentication); 
} 

} 

請讓我知道問題出在哪裏。我不希望這張地圖是空的。

-----更新------

當新用戶登錄的話,我可以看到所有的用戶已經在LinkedHashMap的增加。此方法內的用戶服務類中的一種:

@Service("userService") 
    public class UserServiceImpl implements UserService { 

    @Autowired 
    UsersLoggedInService usersLoggedInService; 

    @Override 
public User getUserDetail() { 
    Authentication auth = SecurityContextHolder.getContext() 
      .getAuthentication(); 
    Object principal = auth.getPrincipal(); 
     if(principal instanceof User){ 
      User user = (User) principal; 
      usersLoggedInService.setOnlineUsers(user.getId(), user.getUsername()); 

      return user; 
     } 
     return null; 
} 

}

當登錄的用戶假設兩個用戶登錄,我得到地圖爲{1 =用戶1,9 =用戶2},但如果任何的用戶註銷然後內部onLogoutSuccess()方法我得到地圖值爲{}。現在如果有多個用戶登錄,那麼我得到地圖{1 = user1,9 = user2,3 = user3}。因此,Map僅在LogoutSuccess()方法內部變空,並且它在其他地方顯示填充值。

回答

4

從您所描述的看起來,它是爲處理程序創建的新服務實例。

這可能是你的配置的默認範圍不是單身(它應該很容易檢查)。

另外,你可否請嘗試使用@Autowired註釋?有一個從文檔@Autowire@Resource之間細微的差別看起來它應該不會造成這樣的問題,但值得一試反正:

@Component 
public class MyLogoutHandler extends SimpleUrlLogoutSuccessHandler { 

    @Autowired 
    private UsersLoggedInsService usersLoggedInService; 

    // ... 
} 

-----更新#1 ------

葉氏,嘗試用@Autowired@Qualifier(當我試過,例如無修飾春創建了兩個實例):

@Autowired 
    @Qualifier("usersLoggedInService") 
    UsersLoggedInService usersLoggedInService; 

----更新#2 ------

好吧,我只是簡單地複製了你的代碼示例中的所有代碼和it works on my machine

是否有可能在GitHub這樣的服務上共享您的代碼庫?

+0

嗨,Petro,它仍然是我改爲@Autowired,但仍然LinkedHashmap是空的,當我註銷。我沒有在任何地方指定我的範圍 – user965884

+0

我想我知道問題在哪裏。你可以請張貼代碼在你自動裝配usersLoggedInService負責添加登錄用戶的類 –

+0

您好Petro,我已經更新了我的代碼。請檢查 – user965884

1

請顯示正在調用setOnlineUsers的班級。以及在什麼地方檢查地圖不是空的?

嘗試將方法onLogoutSuccess中的記錄器,並檢查是否得到一個新的或相同的實例UsersLoggedInService

而我假設你有一個輸入錯誤的bean,你正在接線UsersLoggedIn * s *服務。有一個額外的's'

+0

嗨Parvez,我已經更新了我的問題,並添加了地圖不是空的方法。 – user965884

+0

我看不出任何代碼有問題。爲了指出問題,你是否可以檢查方法onLogoutSuccess,如果你正在得到一個新的或相同的UsersLoggedInService實例?你可以打印bean的hashCode()來驗證這一點。 – Parvez

+0

嗨Parvez,我更新了我的問題,請檢查 – user965884