中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何解決Spring自動注入失敗的問題

發布時間:2021-05-12 14:25:07 來源:億速云 閱讀:761 作者:小新 欄目:開發技術

小編給大家分享一下如何解決Spring自動注入失敗的問題,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

Spring自動注入失敗如何解決?

我有一個被Spring @Service注解的類(MileageFeeCalculator),它有一個用@Autowired注入的變量(rateService),但是當我用這個變量的時候,它顯示為null。日志顯示MileageFeeCalculator bean和MileageRateService bean都被創建了,但是當我調用service上的mileageCharge ()方法時,就會報NullPointerException錯誤。為什么Spring不能自動注入這個實例?

Controller:

@Controller
public class MileageFeeController {    
    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        MileageFeeCalculator calc = new MileageFeeCalculator();
        return calc.mileageCharge(miles);
    }
}

Service:

@Service
public class MileageFeeCalculator {

    @Autowired
    private MileageRateService rateService; // <--- should be autowired, is null

    public float mileageCharge(final int miles) {
        return (miles * rateService.ratePerMile()); // <--- throws NPE
    }
}

本應被注入Service但是并沒有的類

@Service
public class MileageRateService {
    public float ratePerMile() {
        return 0.565f;
    }
}

為什么我調用GET /mileage/3這個請求的時候,會報這樣的錯誤:

java.lang.NullPointerException: null
    at com.chrylis.example.spring_autowired_npe.MileageFeeCalculator.mileageCharge(MileageFeeCalculator.java:13)
    at com.chrylis.example.spring_autowired_npe.MileageFeeController.mileageFee(MileageFeeController.java:14)
    ...

回答

@Autowired注解的字段為null是因為,Spring無法獲取你用new關鍵字創建的類,也無法自動注入它。

Spring Ioc容器有三個主要的邏輯組件:應用程序可以使用的注冊表(ApplicationContext);通過把依賴項與上下文中的bean匹配,將依賴的對象注入的配置器系統;以及一個依賴解析器,它可以查看許多不同bean的配置,并確定如何按必要的順序實例化和配置它們。

Ioc容器并沒有魔法,除非你以某種方式通知它,否則它無法獲取Java對象。當你調用new創建對象時,JVM實例化新對象,并將其中一個副本交給你——它并不經歷Spring的配置過程。有三種方法可以配置bean實例。

注入你的bean

最好的選擇是讓Spring注入所有的bean;這樣的代碼量會最少并且也最容易維護。為了使注入如你所愿,需要把MileageFeeCalculator像這樣注入。

@Controller
public class MileageFeeController {

    @Autowired
    private MileageFeeCalculator calc;

    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        return calc.mileageCharge(miles);
    }
}

如果你需要為不同的請求都創建一個類的新實例,可以通過Spring注解的scopes實現。

使用@Configurable

如果你真的需要把new出來的對象保存進行注入,那可以使用Spring的@Configurable注解,通過使用AOP在編譯時織入你的對象中。這種方法將代碼插入到對象的構造函數中,提醒Spring這個對象正在被創建,這樣Spring就能夠配置新實例了。這需要你添加一些配置信息。并打開Spring的運行時配置處理器。Roo Active Record系統使用這種方法來允許實體的new實例獲取注入的必要持久性信息。

@Service
@Configurable
public class MileageFeeCalculator {

    @Autowired
    private MileageRateService rateService;

    public float mileageCharge(final int miles) {
        return (miles * rateService.ratePerMile());
    }
}

手動查找bean:不推薦

這種方法只適用于在特殊情況下與遺留代碼對接。創建一個Spring可以自動注入并且遺留代碼也能調用的單例適配器總是可取的,但是也許可以直接向spring application context請求bean實例。

為了做到這點,你需要一個類,該類提供了對ApplicationContext對象的引用

@Component
public class ApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;   
    }

    public static ApplicationContext getContext() {
        return context;
    }
}

之后你的遺留代碼就可以調用getContext()方法獲取所需的bean實例了。

@Controller
public class MileageFeeController {    
    @RequestMapping("/mileage/{miles}")
    @ResponseBody
    public float mileageFee(@PathVariable int miles) {
        MileageFeeCalculator calc = ApplicationContextHolder.getContext().getBean(MileageFeeCalculator.class);
        return calc.mileageCharge(miles);
    }
}

以上是“如何解決Spring自動注入失敗的問題”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

廊坊市| 滁州市| 吴旗县| 蒙山县| 和田市| 阿克苏市| 大竹县| 宁阳县| 兴和县| 西安市| 加查县| 颍上县| 泽普县| 光泽县| 昭通市| 深州市| 和林格尔县| 中牟县| 资中县| SHOW| 多伦县| 上犹县| 安康市| 门源| 烟台市| 信阳市| 延津县| 祁门县| 锡林浩特市| 余姚市| 汾阳市| 子长县| 永泰县| 东辽县| 福贡县| 嵊泗县| 宁晋县| 光山县| 廊坊市| 垫江县| 右玉县|