Skip to main content

整合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);
note

需要在方法里面的局部变量调用RedisUtil redisUtil = SpringUtil.getBean(RedisUtil.class);才可以,不能放在全局变量,因为在全局变量的话,在applicationContext还没set的时候被调用getBean方法,这时的applicationContextnull,会报空指针异常。