spring中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;
}
}
当用户登录时假设有两个用户登录我得到Map为{1 = user1,9 = user2}但是如果任何用户注销然后在onLogoutSuccess()方法内,我得到地图值为{}。现在,如果再有一个用户登录,那么我得到地图{1 = user1,9 = user2,3 = user3}。因此,Map仅在onLogoutSuccess()方法中变为空,并且在其他地方显示填充值。
答案 0 :(得分: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等服务上分享您的代码库?
答案 1 :(得分:1)
请显示正在调用setOnlineUsers
的班级。你是如何以及在什么地方检查地图不是空的?
尝试在方法onLogoutSuccess
中放入记录器,并检查您是否获得了UsersLoggedInService
的新实例或相同实例。
我假设您在bean中有一个拼写错误,您正在连接UsersLoggedIn * s *服务。还有一个's'