WebSocket Scope

    每个 WebSocket 会话都有一个属性 map(attributes map)。该 map 作为 header 附在入站的客户端消息中,并可从控制器方法中访问,如下例所示:

    1. @Controller
    2. public class MyController {
    3. @MessageMapping("/action")
    4. public void handle(SimpMessageHeaderAccessor headerAccessor) {
    5. Map<String, Object> attrs = headerAccessor.getSessionAttributes();
    6. // ...
    7. }
    8. }

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

    1. @Component
    2. @Scope(scopeName = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
    3. public class MyBean {
    4. @PostConstruct
    5. public void init() {
    6. // 在依赖关系注入后被调用
    7. }
    8. // ...
    9. @PreDestroy
    10. public void destroy() {
    11. // 当 WebSocket 会话结束时被调用
    12. }
    13. }
    14. @Controller
    15. public class MyController {
    16. private final MyBean myBean;
    17. @Autowired
    18. public MyController(MyBean myBean) {
    19. this.myBean = myBean;
    20. }
    21. @MessageMapping("/action")
    22. public void handle() {
    23. // 当前 WebSocket 会话中的 this.myBean
    24. }
    25. }

    与任何自定义作用域一样,Spring 在第一次从控制器访问 MyBean 时初始化一个新的 MyBean 实例,并将该实例存储在 WebSocket 会话属性中。随后会返回相同的实例,直到会话结束。如前面的例子所示,WebSocket 作用域的 Bean 有所有 Spring 生命周期方法被调用。