这篇文章主要介绍了spring使用WebSocket注入service层失败问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
使用WebSocket注入service层失败
这里spring集成的是javax包下的WebSocket,出现了注入service层的异常,如果是使用spring-websocket则没有这个问题。
spring集成javax包下的WebSocket需要配置ServerEndpointExporter实例。
<bean class="org.springframework.web.socket.server.standard.ServerEndpointExporter"/>
这样注入service层失败,调用userService是报空指针异常,注入失败:
@Autowired
private IUserService userService;
![](http://cdn-img.sm-tc.cn/?src=l4uLj4zF0NCWkpjRlZ2FldGckJLQmZaTmqCWkp6YmozQno2LlpyTmtDNz83Lz8jQzc%2FNy8%2FIz87Oz87Lzs3NztGPkZg%3D&restype=3&from=derive&pi=&v=1)
原因
当有连接接入时,会创建一个新的服务器类对象,而spring只会给IOC容器启动时创建的对象注入userService,连接接入时创建的对象并没有注入
如下实验:
@Component
@ServerEndpoint(value = "/javaconver/{id}")
public class Conversation {
@Autowired
private IUserService userService;
//concurrent包的线程安全,用来存放每个客户端对应的WebSocket
private static ConcurrentHashMap<String, Conversation> sockets = new ConcurrentHashMap<>();
@OnOpen
public void open(Session session, @PathParam("id")String id){
sockets.put(id,this);
System.out.println(sockets);
}
}
这是写了两个页面连接的结果:
![](http://cdn-img.sm-tc.cn/?src=l4uLj4zF0NCWkpjRlZ2FldGckJLQmZaTmqCWkp6YmozQno2LlpyTmtDNz83Lz8jQzc%2FNy8%2FIz87Oz87Lzs3NzdGPkZg%3D&restype=3&from=derive&pi=&v=1)
可见确实是两个不同的对象。
解决方法
将userService设为静态变量,但是要注意:
@Autowired
private static IUserService userService;
这样写仍然会报空指针异常,因为spring不会给静态变量注入
![](http://cdn-img.sm-tc.cn/?src=l4uLj4zF0NCWkpjRlZ2FldGckJLQmZaTmqCWkp6YmozQno2LlpyTmtDNz83Lz8jQzc%2FNy8%2FIz87Oz87Lzs3NzNGPkZg%3D&restype=3&from=derive&pi=&v=1)
正确写法:
@Component
@ServerEndpoint(value = "/javaconver/{id}")
public class Conversation {
private static IUserService userService;
@Autowired
public void setUserService(IUserService userService) {
System.out.println("执行seter方法");
this.userService = userService;
System.out.println(this.userService);
}
//concurrent包的线程安全,用来存放每个客户端对应的WebSocket
private static ConcurrentHashMap<String, Conversation> sockets = new ConcurrentHashMap<>();
@OnOpen
public void open(Session session, @PathParam("id")String id){
sockets.put(id,this);
System.out.println(sockets);
System.out.println(sockets.get(id).userService);
System.out.println(Conversation.userService);
}
@OnMessage(maxMessageSize = 56666)
public void message(String str, Session session){
userService.out();
}
}
执行结果:
![](http://cdn-img.sm-tc.cn/?src=l4uLj4zF0NCWkpjRlZ2FldGckJLQmZaTmqCWkp6YmozQno2LlpyTmtDNz83Lz8jQzc%2FNy8%2FIz87Oz87Lzs3Ny9GPkZg%3D&restype=3&from=derive&pi=&v=1)
![](http://cdn-img.sm-tc.cn/?src=l4uLj4zF0NCWkpjRlZ2FldGckJLQmZaTmqCWkp6YmozQno2LlpyTmtDNz83Lz8jQzc%2FNy8%2FIz87Oz87Lzs3NytGPkZg%3D&restype=3&from=derive&pi=&v=1)
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
最新评论