首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Spring 定時任務空指針異常:雙重配置導致 Bean 未注入

     編輯:程式設計綜合問答

問題現象

Quartz 定時任務執行 execute() 時,調用 Service 方法報 NullPointerException,pipeResAction 為 null。

根因分析

配置文件中同一 Bean 定義了兩次(或父子上下文重複掃描),導致:

  1. Quartz Job 實例由 Spring 管理,注入了 pipeResAction。
  2. 但 StartupApp.getInstance().getAppContext().getBean("reportpiperesource") 從另一個上下文獲取 Bean,該上下文中該 Bean 未正確初始化/注入。

代碼片段對比

<!-- 定時任務 Job -->
<bean class="com.boco.auto.AutoIPV6BusinessAlarmStatisticsReport"> ... </bean>

<!-- Action Bean 定義了兩次?不同 id 或父子上下文 -->
<bean id="reportpiperesource" class="com.boco.web.struts.action.report.ReportCommonActionPipeRes" parent="baseAction"> ... </bean>
<bean id="vendorFaultReportService" class="com.boco.alarm.service.impl.VendorFaultReportServiceImpl"> ... </bean>

解決方案

  1. 統一上下文:確保 Quartz Job、Service、Action 都在同一個 Spring ApplicationContext 中定義,避免父子上下文隔離導致 Bean 不可見。
  2. 移除重複定義:檢查 XML 配置,刪除重複的 <bean> 定義,或統一 id。
  3. 優先使用 @Autowired 注入:在 Job 類中直接 @Autowired private ReportCommonActionPipeRes pipeResAction;,避免手動 getBean() 依賴上下文查找順序。
  4. 實現 ApplicationContextAware:若必須手動獲取,讓 Job 實現 ApplicationContextAware,在 setApplicationContext 中保存引用,而非依賴單例工具類 StartupApp。

修正後 Job 類

@Component
public class AutoAlarmStatisticsReport implements Job {
  private static final Logger logger = LoggerFactory.getLogger(AutoAlarmStatisticsReport.class);

  @Autowired
  private ReportCommonActionPipeRes pipeResAction; // 直接注入

  @Override
  public void execute(JobExecutionContext context) {
    logger.info("+++ 進入定時任務 +++");
    generateReport();
  }

  private void generateReport() {
    pipeResAction.insertBusinessNEStatistics("IPV6BusinessAlarmStatistics");
  }
}

總結

Spring 定時任務空指針多因上下文隔離或重複 Bean 定義導致依賴未注入。統一上下文、優先使用註解驅動注入、避免手動 getBean() 是根治之道。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved