WebSocket 范围
每个WebSocket会话都有一组属性的映射(map)。这个映射作为头部信息附加在传入的客户端消息中,可以从控制器方法中访问,如下例所示:
@Controller
public class MyController {
@MessageMapping("/action")
public void handle(SimpMessageHeaderAccessor headerAccessor) {
Map<String, Object> attrs = headerAccessor.getSessionAttributes();
// ...
}
}
你可以在 websocket 范围内声明一个由 Spring 管理的bean。你可以将属于 websocket 范围的 bean 注入到控制器中,以及任何注册在 clientInboundChannel 上的通道拦截器中。这些 bean 通常是单例(singleton),其生命周期比任何单个 WebSocket 会话都要长。因此,你需要在代理模式下使用属于 websocket 范围的 bean,这可以通过使用 @WebSocketScope 注解来方便地实现:
@Component
@WebSocketScope
public class MyBean {
@PostConstruct
public void init() {
// Invoked after dependencies injected
}
// ...
@PreDestroy
public void destroy() {
// Invoked when the WebSocket session ends
}
}
@Controller
public class MyController {
private final MyBean myBean;
@Autowired
public MyController(MyBean myBean) {
this.myBean = myBean;
}
@MessageMapping("/action")
public void handle() {
// this.myBean from the current WebSocket session
}
}
与任何自定义作用域一样,Spring在控制器首次访问MyBean时会初始化一个新的实例,并将该实例存储在WebSocket会话属性中。此后,在会话结束之前,每次都会返回同一个实例。如前面的示例所示,WebSocket作用域的Bean会执行所有的Spring生命周期方法。