Java Spring启动会话管理-为什么有两个sessionRegistry实例?
我试图在我的Spring Boot应用程序中实现“强制注销”功能(例如,管理员禁用用户帐户后) 我按照各种教程中指定的步骤访问会话注册表,以便使用户的会话过期(还有) 但是,在将SessionRegistryImpl注册为@Bean之后,在使用调试器时,我看到依赖项注入机制中有两个不同的实例:Java Spring启动会话管理-为什么有两个sessionRegistry实例?,java,spring,spring-mvc,spring-boot,spring-security,Java,Spring,Spring Mvc,Spring Boot,Spring Security,我试图在我的Spring Boot应用程序中实现“强制注销”功能(例如,管理员禁用用户帐户后) 我按照各种教程中指定的步骤访问会话注册表,以便使用户的会话过期(还有) 但是,在将SessionRegistryImpl注册为@Bean之后,在使用调试器时,我看到依赖项注入机制中有两个不同的实例: Spring Security在登录和注销时使用一个sessionRegistry实例,并按预期保存主体和会话。下面的屏幕截图是在登录后拍摄的-我在registerNewSession()方法中有一个断
- Spring Security在登录和注销时使用一个sessionRegistry实例,并按预期保存主体和会话。下面的屏幕截图是在登录后拍摄的-我在registerNewSession()方法中有一个断点。请注意id和已登录用户的地图。
- 另一个sessionRegistry实例只提供给我自己的SessionManager类,它需要sessionRegistry作为依赖项并调用GetAllPrinciples()。注意,id是不同的,映射是空的(我在多次登录并拍摄第一个屏幕截图后调用了getAllPrincipals()
@Component
class DefaultSessionManager implements SessionManager {
private final SessionRegistry sessionRegistry;
@Autowired public DefaultSessionManager(SessionRegistry sessionRegistry) {
this.sessionRegistry = sessionRegistry;
}
public void expireUserSessions(String username) {
for (Object principal : sessionRegistry.getAllPrincipals()) {
// do stuff, but won't enter because the list is empty
}
}
}
如果有帮助的话,我会使用exactor/beans端点查找bean设置,这就是它返回的结果
{
"bean": "defaultSessionManager",
"aliases":
[
],
"scope": "singleton",
"type": "com.foo.bar.DefaultSessionManager",
"resource": // file path
"dependencies":
[
"sessionRegistry"
]
},
{
"bean": "httpSessionEventPublisher",
"aliases":
[
],
"scope": "singleton",
"type": "org.springframework.security.web.session.HttpSessionEventPublisher",
"resource": "class path resource [com/foo/bar/SecurityConfig.class]",
"dependencies":
[
]
},
{
"bean": "sessionRegistry",
"aliases":
[
],
"scope": "singleton",
"type": "org.springframework.security.core.session.SessionRegistryImpl",
"resource": "class path resource [com/foo/bar/SecurityConfig.class]",
"dependencies":
[
]
},
如果所有实例都声明为单实例,那么DI系统中怎么会有两个不同的实例?
你有什么关于什么可能是错误的提示吗
我使用的是spring boot starter父级1.5.2.RELEASE,它使用spring Security 4.2.2.RELEASE。问题是
@Bean
注释方法上的静态关键字。在您调用
.sessionRegistry(sessionRegistry())
它直接调用静态方法,而不是通过Spring代理从应用程序上下文获取bean。这意味着,对于您的安全配置,您将创建一个新实例,而不是从应用程序上下文获取bean。对于非静态方法,Spring会截取相同调用中的直接方法调用,然后检查bean是否已经存在于应用程序上下文中,如果存在,则返回bean。我不知道它是否相关,但是使用
@bean
注释的方法不需要是静态的。由于Spring在配置类中使用代理等,这可能是个问题,但我不确定。也许可以尝试删除静态关键字。我在春天遇到了这样的问题。可以显示引用会话注册表的对象吗?在我的例子中,应用程序中有上下文。实际上,我认为静态关键字是问题所在,因为在您调用.sessionRegistry(sessionRegistry())
的配置中,它会直接调用静态方法,而不是通过Spring代理从应用程序上下文获取bean。这意味着,对于您的安全配置,您将创建一个新实例,而不是从应用程序上下文获取bean。谢谢,@dunni,就是这样。我移除了静电场,它现在可以工作了。。。我还没想到。如果你愿意,请将此作为答案发布,我会接受。干杯谢谢,在这一点上,他们不是很有帮助。但我会记住未来。这里发生了很多神奇的事情。一个普遍的经验法则(不是官方的,只是从我这边):静态和弹簧通常不能很好地结合在一起。
.sessionRegistry(sessionRegistry())