Quarkus中@ApplicationScoped Bean注入的JsonWebToken为何每次值不同?
问题分析与解释
1. clientIdGlobal的表现符合预期
你说的没错:因为WebSocket加了@ApplicationScoped注解,整个应用里只会存在这一个实例,所有客户端的WebSocket连接都会共用它。所以后续连接的客户端会覆盖clientIdGlobal的值,不管哪个方法里取到的都是最后一个连接的客户端ID,这就是单实例Bean的正常行为。
2. 类级注入的JsonWebToken为何能动态对应客户端
这是Quarkus(以及Jakarta EE/MicroProfile生态)中依赖注入的代理机制在起作用,具体逻辑如下:
JsonWebToken默认是与单个客户端连接绑定的作用域Bean:每个客户端的WebSocket连接都会对应一个独立的JsonWebToken实例,存储着该客户端专属的令牌信息,它的生命周期和连接完全绑定。- 你注入的并非真实JWT实例,而是代理对象:由于
WebSocket是单实例的@ApplicationScopedBean,而JsonWebToken是作用域更窄的Bean,直接注入真实实例会导致作用域冲突。因此Quarkus会自动生成一个JsonWebToken的代理对象,注入到WebSocket实例中。 - 调用方法时才会动态获取对应客户端的真实JWT:当你在
OnOpen、OnMessage等方法中调用jsonWebToken.getClaim()时,代理对象会先检查当前的执行上下文——Quarkus在处理WebSocket事件时,会将当前连接对应的安全上下文(包含该客户端的JWT)绑定到当前线程。代理会从这个上下文里取出对应客户端的真实JsonWebToken实例,所以你每次调用都能拿到当前客户端的令牌,看起来像是动态变化的。
说白了,你注入的不是固定的JWT对象,而是一个“中间商”,每次调用它的方法时,它都会去当前连接的上下文里取对应客户端的真实JWT来用。
内容的提问来源于stack exchange,提问作者Nithin B
相关产品推荐
相关产品推荐

