SpringBoot中@Autowired 失效及@Autowired 注入為null的解決
一、問題
使用@Atuowried注入Bean失敗,導致空指針異常。
二、大致背景
SpringBoot版本:2.6.14,基于SpringSecurity實現(xiàn)郵箱驗證碼登錄功能。EmailCodeAuthenticationSuccessHandler為郵件驗證碼登錄認證成功的Handler,實現(xiàn)認證成功后返回響應,響應體為登錄用戶名以及JWTUtil生成的token。EmailCodeAuthenticationSuccessHandler中使用@Atuowried將JWTUtil自動注入進來。
JWTUtil:

三、具體報錯:
在生成token時,報了一個空指針異常:
(1)報錯分析
在Spring Security的認證過程中,EmailcodeAuthenticationSuccessHandler類的onAuthenticationSuccess方法的第45行:data.put(“token”, jwtUtil.createToken(userId));,發(fā)生了一個NullPointerException(空指針異常)。

(2)問題定位
data是new出來的JSONObject(),只有可能是JWTUtil注入為null導致空指針異常。
(3)斷點調(diào)試

bingo!確實是@Atuowried注入失敗,導致jwtUtil為null,從而在調(diào)用createToken方法時出現(xiàn)空指針異常。
四、具體問題
為什么@Atuowried注入失敗/@Atuowried注入為null
查各類博客總結(jié)如下:
(1)被注入的對象沒有加載到Spring容器中
? 缺少@Component之類的注解或者沒有被Spring掃描到。
(2)自定義配置存在問題
? 自定義的BeanFactory沒有正確配置,導致Spring容器無法識別自定義的Bean。
(3)被注入的對象不是Spring加載
? 通過反射或者熱部署加載的類Spring無法根據(jù)注解自動注入。
(4)需要自動注入的對象存在被new出來的實例
? 對象new實例化后,導致對象沒有交給Spring容器管理,所以無法自動注入。一般是指引用某些框架,自定義了類繼承某個接口,但是在這些框架中默認new過這個類,比如MVC攔截的HandlerInterceptor類。如果要new的這個類里有需要@autowired 自動注入的內(nèi)容,則自動注入無效。
五、本問題的原因
在LoginServiceImpl中注入JWTUtil正常,問題出在接口AuthenticationFailureHandler上。可能是SpringSecurity 通過new創(chuàng)建過 EmailcodeAuthenticationSuccessHandler的實例,導致其無法實現(xiàn)自動注入。
六、解決方案
確實需要在這個new 的類去注入某些類,但是用@Autowired 又注入為null,這時候就需要去實現(xiàn)ApplicationContextAware接口,拿到IOC容器,實現(xiàn)手動獲取Bean。
(1)具體代碼:
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @Description 一個類實現(xiàn)了ApplicationContextAware接口后,就可以獲得ApplicationContext中的所有bean
* 用于解決某些類因為有被new出來的實例導致@Autowired失效的問題
* @Author wxp
* @Date 2024/7/9 12:47
*/
@Component
public class BeanUtils implements ApplicationContextAware {
protected static ApplicationContext applicationContext;
/**
* 實現(xiàn)ApplicationContextAware接口的回調(diào)方法,設(shè)置上下文環(huán)境
* @param arg spring上下文對象
* @throws BeansException 拋出spring異常
*/
@Override
public void setApplicationContext(ApplicationContext arg) throws BeansException {
if (applicationContext == null) {
applicationContext = arg;
}
}
/**
* 獲取spring上下文對象
* @return 上下文對象
*/
public static ApplicationContext getContext() {
return context;
}
/**
* 根據(jù)beanName獲取bean
* @param beanName bean的名稱
* @return bean對象
*/
public Object getBean(String beanName) {
return context.getBean(beanName);
}
/**
* 根據(jù)beanName和類型獲取bean
* @param beanName bean名稱
* @param clazz bean的Class類型
* @param <T> bean的類型
* @return bean對象
*/
public <T> T getBean(String beanName, Class<T> clazz) {
return context.getBean(beanName, clazz);
}
/**
* 根據(jù)類型獲取bean
* @param clazz bean的Class類型
* @param <T> bean的類型
* @return bean對象
*/
public <T> T getBean(Class<T> clazz) {
return context.getBean(clazz);
}
}
(2)具體使用:
JWTUtil jwtUtil = BeanUtils.getBean(JWTUtil.class);
到此這篇關(guān)于SpringBoot中@Autowired 失效及@Autowired 注入為null的解決的文章就介紹到這了,更多相關(guān)SpringBoot @Autowired 失效內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java C++題解leetcode1620網(wǎng)絡(luò)信號最好的坐標
這篇文章主要為大家介紹了Java C++題解leetcode1620網(wǎng)絡(luò)信號最好的坐標示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-01-01
Java Swing窗體關(guān)閉事件的調(diào)用關(guān)系
這篇文章主要為大家詳細介紹了Java Swing窗體關(guān)閉事件的調(diào)用關(guān)系,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-07-07
java中循環(huán)遍歷刪除List和Set集合中元素的方法(推薦)
下面小編就為大家?guī)硪黄猨ava中循環(huán)遍歷刪除List和Set集合中元素的方法(推薦)。小編覺得挺不錯的,在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-12-12
SpringBoot過濾器與攔截器深入分析實現(xiàn)方法
大家應該都曉得實現(xiàn)過濾器需要實現(xiàn) javax.servlet.Filter 接口,而攔截器會在處理指定請求之前和之后進行相關(guān)操作,配置攔截器需要兩步,本文通過實例代碼給大家介紹SpringBoot 過濾器和攔截器的相關(guān)知識,感興趣的朋友一起看看吧2022-11-11
MybatisPlus使用Wrapper實現(xiàn)條件查詢功能
這篇文章主要介紹了MybatisPlus使用Wrapper實現(xiàn)查詢功能,使用它可以實現(xiàn)很多復雜的查詢,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-06-06

