整合WebSocket和Redis
背景
SpringBoot
项目中,在WebSocket
中想使用Redis
。把自己编写的RedisUtils
使用@Autowired
自动注入到当前类。
在运行时,出现异常:java.lang.NullPointException
,找不到RedisUtils
原因
- 自己编写的
RedisUtils
没有放到spring
容器中(导致没有实例化)。经过测试,排除此原因。(简单的通过一个Controller
中操作redis
判断即可,或者直接取出所有的bean看下是否存在。) WebSocket
是多对象的,使用的spring
却是单例模式。这两者刚好冲突。@Autowired
注解注入对象是在启动的时候就把对象注入,而不是在使用A
对象时才把A
需要的B
对象注入到A
中。而WebSocket
在刚刚有说到,有连接时才实例化对象,而且有多个连接就有多个对象。由此得知,RedisUtils
根本就没有注入到WebSocket
当中。
解决方法
方法一
让RedisUtils
属于WebSocketServer
这个类。
private static RedisUtils redisUtils;
@Autowired
public void setRedisUtils(RedisUtils redisUtils) {
WebSocketServer.redisUtils = redisUtils;
}
方法二
编写从容器中取对象的工具类
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringUtil.applicationContext = applicationContext;
}
public ApplicationContext getApplicationContext(){
return applicationContext;
}
public static Object getBean(String beanName){
return applicationContext.getBean(beanName);
}
public static <T> T getBean(Class<T> clazz){
return (T)applicationContext.getBean(clazz);
}
}
然后再在WebSocket
中
RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);
备注
需要在方法里面的局部变量调用RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);
才可以,不能放在全局变量,因为在全局变量的话,在applicationContext
还没set
的时候被调用getBean
方法,这时的applicationContext
是null
,会报空指针异常。