springboot 的 websocket 里面使用 @Autowired 注入 service 或 bean 时,报空指针异常,service 为 null(并不是不能被注入)。
解决方法:将要注入的 service 或 bean 改成 static,在使用时,就不会为null了。
直接上代码:
@Controller
@ServerEndpoint(value="/chatSocket")
public class ChatSocket {
// webSocket 会生成多个对象,而psring的单例模式只会注入一次,所以用 static
private static ChatService chatService;
private Session session;
@Autowired
public void setChatService(ChatService chatService) {
ChatSocket.chatService = chatService;
}
本质原因:spring管理的都是单例(singleton)对象,和 websocket (多对象)相冲突。
详细解释:项目启动时初始化,会创建第一个 websocket (非用户连接),spring 会为其注入 service,该对象的 service 不是 null。但是,由于 spring 默认管理的是单例,所以只会注入一次 service。当新用户进入聊天时,系统又会创建一个新的 websocket 对象,这时矛盾出现了:spring 管理的都是单例,不会给第二个 websocket 对象注入 service,所以导致只要是用户连接创建的 websocket 对象,都不能正常注入!!!
像controller 里面有 service, service 里面有 dao。因为 controller,service ,dao 都有是单例,所以只注入一次不会报 null。但是 websocket 不是单例,所以只注入一次后,后面的对象不能被注入,会报null。