简单来说就是在一个新建模块里,一个如下mapper

@Mapper
public interface ChatRecordMapper {

    @Insert("INSERT INTO chat_record (record_id, user_id, records, create_time) " +
            "VALUES (#{recordId}, #{userId}, #{records}, #{createTime})")
    void insertChatRecord(ChatRecord chatRecord);
}

我确定包路径和mybatis扫描路径没错(因为没动,新建的模块仍然是com.ruoyi…),
在启动类打印了容器的bean也确实有 ChatRecordMapper
但当我用 autowired 注入的时候,无论如何都不成功,调试显示ChatRecordMapper 就是为 null,里面的方法自然也没法执行。

@CrossOrigin
@Component
@ServerEndpoint("/websocket/message")
public class WebSocketServer {
	@Autowired
    private ChatRecordMapper chatRecordMapper;
    ……
}

解决是基于 手动获取bean(SpringUtils.getBean())

虽然不知道为什么,但确实解决了。原因先贴一下gpt的回答,改天再验证:

如果在启动类中打印容器的Bean能够看到该Bean,但是使用@Autowired注入时却为null,可能有以下几个原因:

  1. Bean的扫描范围问题: 确保你的启动类所在的包及其子包都在Spring的扫描范围内。
  2. Bean的命名问题: 确保使用@Autowired注解的字段或方法参数名称与Bean的名称一致,或者使用@Qualifier注解来指定具体要注入的Bean名称。
  3. Bean的作用域问题: 如果Bean的作用域设置为prototype,那么每次注入都会创建一个新的实例。如果你在启动类中打印的Bean是在容器初始化时创建的,但@Autowired注入是在后续的代码中进行的,可能会导致注入的是不同的实例,其中一个为null。
  4. 启动顺序问题: 确保启动类的初始化在Spring容器初始化之后。如果启动类中的代码在容器初始化之前执行,那么@Autowired注入可能会失败。
  5. 循环依赖问题: 如果存在循环依赖,Spring可能无法正常注入Bean。确保你的Bean之间没有循环依赖关系。

如果你使用SpringUtils.getBean()可以成功注入Bean,但@Autowired注入失败,可能是因为SpringUtils.getBean()是在容器初始化之后手动获取Bean的,而@Autowired注入可能发生在容器初始化之前,这就解释了为什么前者成功而后者失败。

Logo

快速构建 Web 应用程序

更多推荐