使用WebSocket在Server类中无法使用Autowired注解进行自动注入

683 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第8天,点击查看活动详情

问题

在SpringBoot项目中使用WebSocket的过程中有其他的业务操作需要注入其它接口来做相应的业务操作,但是在WebSocketServer类中使用Autowired注解无效,这样注入的对象就是空,在使用过程中会报空指针异常。

注释:上面说的WebSocketServer类就是指被@ServerEndpoint注解修饰的类

原因

原因就是在spring容器中管理的是单例的,他只会注入一次,而WebSocket是多对象的,当有新的用户使用的时候,他就会新创建一个WebSocket对象,这就导致了用户创建的WebSocket对象都不能注入对象了,所以在运行的时候就会发生注入对象为null的情况;

主要的原因就是Spring容器管理的方式不能直接注入WebSocket中的对象,所以需要调整一下注入方式。

解决办法

把需要注入的对象声明为静态对象,代码如下:

    private static BaseWebSocketService baseWebSocketService;

    @Autowired
    public void setService(BaseWebSocketService baseWebSocketService){
        WebSocketClient.baseWebSocketService = baseWebSocketService;
    }

解释

@Autowired可以对类成员变量方法构造函数进行标注,完成自动装配的工作。

但是使用Autowired标注的类必须由spring容器进行管理,通常都会使用下面的几个注解进行spring容器的托管:

  • @Controller
  • @Service
  • @Mapper
  • @Coponen
  • @repository

如果使用 @Autowired注解的属性没有被装配,在容器中找不到该类型的bean注入,就会报错。如果允许不被装配就可以将 @Autowiredrequired属性为false

@Autowired是基于类型的注入,如果当前类型属性在容器中只有一个Bean, 那么属性名不限制,但一般建议遵循类名首字母小写的规则,如果当前属性类型在容器中有个多个Bean,那么必须要通过属性名 或者 @Qualifier 指定Bean name

Resource注解则是基于名称的注入,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。