上一篇文章我们演示了使用springboot构建一个websocket服务端的案例,我们在代码里面使用到了SocketServerProduct这个类,这个类我们在springboot中习惯使用@Autowired这个注解把他注入进来,但是我们会发现一个问题,就是我们使用Autowired注入这个类之后,运行的时候会报空指针异常,这是为什么呢?对此的解释是:
Spring管理采用单例模式(singleton),而 WebSocket 是多对象的,即每个客户端对应后台的一个 WebSocket 对象,也可以理解成 new 了一个 WebSocket, 这样当然是不能获得自动注入的对象了,因为这两者刚好冲突。
也就是相当于websocket是每次会new一个的,这里new之后,就无法加载 spring注入的类。因此这里如果直接使用@Autowired的话,就没法初始化对应的实例,因此直接就会报空指针异常。
那么我们既然在springboot项目中创建的webscoket,结合springboot的习惯大多数类及配置都需要使用@Autowired来注入,那怎么办呢?其实有两个办法:
第一个办法直接new
这里就像我们上一段示例里面我们是直接使用的:
private SocketServerProduct socketServerProduct = new SocketServerProduct();
这种对于单个的实例来说没什么问题,试想下,再springboot中,我们需要使用的mysql,redis等,那是不是要全部自己去new,然后写各种jdbc连接呢?那肯定是不行的,因此有第二种方法。
第二个办法使用@Autowired
第二个办法的代码如下:
private static SocketServerProduct socketServerProduct; @Autowired public void setService(SocketServerProduct socketServerProduct){ WebSocketServer.socketServerProduct = socketServerProduct; }
这里我们还是使用到了@Autowired这个注解,但是我们其实核心是把想要做的类做成static的,所以我们申明变量的时候,使用的是如下的static修饰
private static SocketServerProduct socketServerProduct;
然后我们在下面编写一个手动的set注入类,例如:
@Autowired public void setService(SocketServerProduct socketServerProduct){ WebSocketServer.socketServerProduct = socketServerProduct; }
这样子,像springboot其他的这些spring相关的注入都可以在websocket里面使用了。
以上就是解决在@ServerEndpoint标注的webscoket中不能使用@Autowired的解决方案。
备注:
1、网上还提供一种springutils.getbeans()的方法,在本地我测试一直没成功,也是报空指针异常。
最后按照惯例,附上本案例的源码,登录后即可下载。
还没有评论,来说两句吧...