SpringBoot项目WebSocket内@Autowired注入MyBatis Mapper为空如何解决?
问题根因
- 只有被Spring容器管理的Bean,其内部的
@Autowired、@Resource等注解才会被Spring自动装配依赖 - 你手动
new VaService()生成的实例没有纳入Spring容器生命周期,内部依赖的VaMapper自然不会被注入,所以触发空指针
可行解决方案
方案1:通过Spring上下文工具类获取已经被Spring管理的VaService实例
这是改造成本最低的常用方案,不需要改动原有Service和Mapper的配置
- 先实现Spring上下文工具类,用于从容器中获取已装配完成的Bean
import org.springframework.beans.BeansException; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; @Component public class SpringContextUtil implements ApplicationContextAware { private static ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { SpringContextUtil.applicationContext = applicationContext; } // 根据类类型获取对应Bean实例 public static <T> T getBean(Class<T> clazz) { return applicationContext.getBean(clazz); } }
- 在Jetty管理的
SimpleEchoSocket类中,不要手动new VaService,直接通过工具类获取实例:
// 替换原有手动实例化的代码 VaService vaService = new VaService(); VaService vaService = SpringContextUtil.getBean(VaService.class);
- 拿到的VaService是Spring已经完成所有依赖注入的实例,内部的VaMapper已经被正确装配,可以直接调用业务方法
方案2:把WebSocket类也交给Spring管理
如果业务逻辑允许调整WebSocket的实例化规则,可以直接让Spring托管SimpleEchoSocket,之后直接注入VaService即可:
- 在
SimpleEchoSocket类上添加@Component注解,默认是单例模式,如果需要每次连接生成新实例可额外添加@Scope("prototype")注解 - 调整Jetty的WebSocket注册逻辑,从Spring容器中获取
SimpleEchoSocket实例再注册,不要让Jetty自行实例化该类
注意事项
- 不要手动new被Spring管理的Bean(加了
@Service、@Component、@Repository等注解的类),手动new的实例Spring不会处理其内部依赖 - MyBatis的Mapper是框架动态代理生成的实例,已经自动注册到Spring容器中,不需要手动实例化,只要是Spring管理的Bean都可以直接注入使用
内容的提问来源于stack exchange,提问作者Julia5049
相关产品推荐
相关产品推荐

