spring boot中依賴注入失敗排查:普通類注入service報錯
在spring boot應用中,我們經常需要將一個普通的Java類注入到service類中使用。然而,如果處理不當,就會出現spring容器找不到bean的錯誤。本文將針對標題中提出的問題進行詳細分析和解答。
問題描述:
開發者在spring boot項目中定義了一個名為printinvoiceservice的普通類,并試圖將其注入到fgstoserviceimpl(一個service類)中。然而,運行程序時卻報出以下錯誤:a component required a bean of type ‘com.haier.cosmo.wms.cp.out.service.service.printinvoiceservice.printinvoiceservice’ that could not be found. 這說明spring容器無法找到printinvoiceservice類型的bean。
問題代碼:
fgstoserviceimpl類:
@service public class fgstoserviceimpl implements fgstoservice { @Resource private printinvoiceservice printinvoiceservice; public transresult printvnpt(odsprostohvdetail condition) { publishservicesoap publishservicesoap = printinvoiceservice.getpublishservicesoap(); // ... } }
printinvoiceservice類:
package com.haier.cosmo.wms.cp.out.service.service.printinvoiceservice; import java.net.malformedurlexception; import java.net.url; public class printinvoiceservice { private publishservicesoap publishservicesoap; public publishservicesoap getpublishservicesoap() { string url = "https://aquavn-tt78admindemo.vnpt-invoice.com.vn/publishservice.asmx"; if (publishservicesoap != null) { return publishservicesoap; } try { url uurl = new url(url); //url在配置文件中動態配置 publishservice mobilecodews = new publishservice(uurl); publishservicesoap = mobilecodews.getpublishservicesoap(); } catch (malformedurlexception e) { e.printstacktrace(); } return publishservicesoap; } }
問題原因及解決方法:
spring容器無法找到printinvoiceservice bean的原因是該類沒有被spring管理。 spring通過注解(例如@component, @service, @controller, @repository)來識別和管理bean。 printinvoiceservice類缺少這些注解,因此spring無法將其實例化并放入容器中。 解決方法是為printinvoiceservice類添加@component注解,將其注冊到spring容器中。
需要注意的是,printinvoiceservice 類內部使用 new publishservice(uurl) 創建了 publishservice 實例。 如果 publishservice 也需要被spring管理,則也需要添加相應的注解,并通過@autowired或@resource注入到printinvoiceservice中,避免直接使用new關鍵字創建對象。 否則,即使printinvoiceservice 被spring管理,其內部的publishservice仍然是獨立于spring容器之外的實例。
如果堅持在printinvoiceservice中使用new publishservice(uurl)這種方式,并且仍然需要通過spring容器獲取printinvoiceservice bean,可以使用一個工具類來手動從spring容器中獲取bean:
@Component public class SpringUtils implements ApplicationContextAware { // ... (代碼與問題答案中提供的一致) ... }
然后在需要的地方使用springutils.getbean(“printinvoiceservice”)獲取printinvoiceservice實例。 但這并非最佳實踐,建議盡量避免在被spring管理的類中直接使用new關鍵字創建對象,而應盡量依賴spring的依賴注入機制。