WebSocket 范围

每个 WebSocket 会话都有一个属性映射。该映射作为标头附加到入站客户端消息,并且可以从控制器方法中访问,如下例所示

@Controller
public class MyController {

	@MessageMapping("/action")
	public void handle(SimpMessageHeaderAccessor headerAccessor) {
		Map<String, Object> attrs = headerAccessor.getSessionAttributes();
		// ...
	}
}

您可以在websocket范围内声明一个 Spring 托管的 Bean。您可以将 WebSocket 范围的 Bean 注入到控制器和在clientInboundChannel上注册的任何通道拦截器中。这些通常是单例,并且比任何单个 WebSocket 会话的寿命更长。因此,您需要对 WebSocket 范围的 Bean 使用范围代理模式,如下例所示

@Component
@Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
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 生命周期方法,如前面的示例所示。