关于javax版本的websocket无法自动填充ioc管理的类实例

来源在 Spring Boot 中整合、使用 WebSocket - spring 中文网

服务可以正常启动,看似一切都没问题!可是当你在事件方法中使用这 Bean 的时候就会导致 NullPointerException 异常。

原因:运行时的  WebSocket 连接对象,也就是端点实例,是由 服务器创建,而不是 Spring,所以不能使用自动装配。上文也提到过 “服务器会为每个连接创建一个端点实例对象”。

知道了原因后,解决办法也很简单,我们可以使用 Spring 的 ApplicationContextAware 接口,在应用启动时获取到 ApplicationContext 并且保存在全局静态变量中。

服务器每次创建连接的时候,我们就在 @OnOpen 事件方法中从 ApplicationContext 获取到需要 Bean 来初始化端点对象。

private static ApplicationContext applicationContext; 的声明通常用于存储 Spring 应用上下文的实例,以便在静态方法中访问 Spring 管理的 Bean。它的主要作用和用途包括:

主要作用

  1. 全局访问:

    • 通过静态方法访问 Spring 容器中的 Bean。这样,你可以在任何地方(即使在非 Spring 管理的类中)获取 Spring Bean 的实例。
  2. 避免手动注入:

    • 如果某个类不是 Spring 管理的 Bean,你可以通过 applicationContext 直接获取其他 Bean,而无需进行显式的依赖注入。

关键代码         EchoChannel.applicationContext.getBean(你想导入的类.class)

@ServerEndpoint(value = "/channel/echo")
@Component  // 由 spring 扫描管理
public class EchoChannel implements
                ApplicationContextAware { // 实现 ApplicationContextAware 接口, Spring 会在运行时注入 ApplicationContext

    private static final Logger LOGGER = LoggerFactory.getLogger(EchoChannel.class);

    // 全局静态变量,保存 ApplicationContext
    private static ApplicationContext applicationContext;

    private Session session;

    // 声明需要的 Bean
    private UserService userService;


    // 保存 Spring 注入的 ApplicationContext 到静态变量
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        EchoChannel.applicationContext = applicationContext;
    }

    @OnOpen
    public void onOpen(Session session, EndpointConfig endpointConfig){
        
        // 保存 session 到对象
        this.session = session;
        
        // 连接创建的时候,从 ApplicationContext 获取到 Bean 进行初始化
        this.userService = EchoChannel.applicationContext.getBean(UserService.class);
        
        // 在业务中使用
        this.userService.foo();
        
        LOGGER.info("[websocket] 新的连接:id={}", this.session.getId());
    }
    // ....
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值