【Java报错】借助@PostConstruct解决使用@Component注解的类用@Resource注入Mapper接口为null的问题(原因解析+解决方法)
1. 說明
有些時候我們需要一個管理類,類似 xxxManager 來處理共享的基礎數據,它要在項目啟動時就進行初始化且查詢數據庫,而且查詢語句不復雜,寫一整套的Service或者使用MyBatis的查詢API有點兒繁瑣,此時寫一個簡單的Mapper接口就優雅許多。
2. 代碼實現
為了簡潔,刪掉部分不必要的備注,下邊是Mapper接口:
/*** 集中管理非單表操作的SQL*/ @Mapper public interface ComplexSqlMapper {// 查詢 view_manager 表全部數據@Select(" select * from view_manager ")List<ViewEntity> getViewManagerAllList(); }下面是管理類,這里沒有使用Doc注釋:
/*** 查詢并處理 view_manager 表數據(為了簡潔這里是示例代碼 真正的處理要比這個復雜)*/ @Component public class ViewManager {// Mapper 注入@Resourceprivate ComplexSqlMapper complexSqlMapper;// 處理結果保存private Map<String, String> views = new HashMap();// 初始化時查詢 view_manager 表數據private ViewManager() {List<ViewEntity> viewEntityList= complexSqlMapper.getViewManagerAllList();// 處理數據viewEntityList.forEach(ve-> {views.put(ve.getId(), ve.getName());});} }3. 原因解析
項目啟動時有NPE,Debug才發現 complexSqlMapper 是null。我首先想到的是 Mapper 文件沒有被檢測到,然后確認了啟動類里的 org.mybatis.spring.annotation.MapperScan 信息:
@SpringBootApplication @MapperScan(basePackages = "com.example.demo.**.mapper") public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);} }并沒有寫錯路徑,那我們仔細回看 ViewManager 類就會發現 complexSqlMapper 是當作類的成員變量被注入的,那也就是說需要先實例化 ViewManager 類然后再注入 complexSqlMapper,可是我們在類的構造器里就調用了 complexSqlMapper 此時構造器沒有執行完,ViewManager 也就沒被實例化,那么 complexSqlMapper 自然是個null。至此通過構造器使用 Mapper 查詢數據的計劃落空了。
4. 問題解決
那就沒有方法了嗎 ? 怎么可能 ?? Spring早就想到了你想到的 😏 使用 @PostConstruct 注解的方法將會在依賴注入完成后被自動調用。
改造后的代碼【這里只貼出核心代碼 無關備注也省略了】
@Component public class ViewManager {@Resourceprivate ComplexSqlMapper complexSqlMapper;private Map<String, String> views = new HashMap();@PostConstructprivate void init() {List<ViewEntity> viewEntityList= complexSqlMapper.getViewManagerAllList();viewEntityList.forEach(ve-> {views.put(ve.getId(), ve.getName());});} }改造后的代碼,項目啟動時由于 @Component 注解,ViewManager 類會被實例化并交給容器管理,此時使用的是 ViewManager 類的無參構造器。而 @PostConstruct 注解的 init 方法會待 complexSqlMapper 注入成功后調用。至此,xxxManager 的功能得以實現。
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的【Java报错】借助@PostConstruct解决使用@Component注解的类用@Resource注入Mapper接口为null的问题(原因解析+解决方法)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Java报错】java.lang.Cl
- 下一篇: 【Java报错】MultipartFil