前言:
当前朋友们对“netcore service为null”大概比较重视,姐妹们都想要剖析一些“netcore service为null”的相关内容。那么小编也在网络上搜集了一些关于“netcore service为null””的相关文章,希望小伙伴们能喜欢,小伙伴们快快来学习一下吧!在Websocket中使用@Autowired注入service时注入失败,service为null。
问题原因
Spring默认对bean的管理都是单例(singleton),和 websocket (多对象)相冲突。
项目启动时初始化,会初始化 websocket (非用户连接的),spring 同时会为其注入 service,该对象的 service 不是 null,被成功注入。但是,由于 spring 默认管理的是单例,所以只会注入一次 service。当用户建立新的连接时,系统又会创建一个新的 websocket 对象,这时不会再次注入了,所以导致只要是用户连接创建的 websocket 对象,都不能再注入了,后面的注入均为null。
解决方法
方法1:使用静态变量 加 @PostConstruct 解决
@ServerEndpoint("/websocket/{userId}") @Component //关键点1 public class WebSocket { @Autowired private UserService userService; private static WebSocket webSocket; //关键点2 @PostConstruct //关键点3 public void init(){ webSocket = this; } //略去其他代码... @OnMessage public void onMessage(String message, Session session) { if(!StringUtils.isEmpty(message)){ try { log.info("收到用户【{}】的消息: {}",this.userId,message); webSocket.userService.helloService(); //关键点4 session.getBasicRemote().sendText("收到 "+this.userId+" 的消息 "); }catch (Exception e){ e.printStackTrace(); } } }}
配置完上述四个关键点,当新建立websocket连接时,@Autowired可成功注入service
方法2:使用静态变量,加set注入
@ServerEndpoint("/websocket/{userId}")@Component //关键点1 public class WebSocket { private static UserService userService; //关键点2 @Autowired //关键点3 public void setUserService (UserService userService){ WebSocket.userService = userService; } //略去其他代码... @OnMessage public void onMessage(String message, Session session) { if(!StringUtils.isEmpty(message)){ try { log.info("收到用户【{}】的消息: {}",this.userId,message); WebSocket.userService.helloService(); //关键点4 session.getBasicRemote().sendText("收到 "+this.userId+" 的消息 "); }catch (Exception e){ e.printStackTrace(); } } } }
配置完上述四个关键点,当新建立websocket连接时,@Autowired也可成功注入service
方法3:使用工具类用于从Spring的上下文中去获取到类的实例
@ServerEndpoint("/websocket/{userId}") @Component //关键点1 public class WebSocket { private static UserService userService = SpringContextHolder.getBean(UserService.class); //关键点2 //略去其他代码... @OnMessage public void onMessage(String message, Session session) { if(!StringUtils.isEmpty(message)){ try { log.info("收到用户【{}】的消息: {}",this.userId,message); userService.helloService(); //关键点3 session.getBasicRemote().sendText("收到 "+this.userId+" 的消息 "); }catch (Exception e){ e.printStackTrace(); } } }}
工具类SpringContextHolder
此工具类用于从Spring的上下文中去获取到类的实例
@Component public class SpringContextHolder implements ApplicationContextAware { private static ApplicationContext applicationContext = null; /** * 取得存储在静态变量中的ApplicationContext. */ public static ApplicationContext getApplicationContext() { return applicationContext; } /* * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. */ @SuppressWarnings("unchecked") public static <T> T getBean(String name) { return (T) applicationContext.getBean(name); } /* * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. */ public static <T> T getBean(Class<T> requiredType) { return applicationContext.getBean(requiredType); } /* * 清除SpringContextHolder中的ApplicationContext为Null. */ public static void clearHolder() { applicationContext = null; } /* * 实现ApplicationContextAware接口, 注入Context到静态变量中. */ @Override public void setApplicationContext(ApplicationContext appContext) { applicationContext = appContext; } }
配置完上述三个关键点,当新建立websocket连接时,@Autowired也可成功注入service
标签: #netcore service为null