Spring 攔截器和過濾器中自動注入為 null 的原因及解決方案
起因
開發過程中在過濾器(filter)中注入Bean出現空指標異常,通過查詢資料瞭解空指標的原因,特此記錄。
問題分析
由於其他bean在service,controller層注入一點問題也沒有,開始根本沒意識到Bean無法注入是在攔截器中無效的問題。
- SpringBoot專案的Bean裝配預設規則是根據Application類所在的包位置從上往下掃描!
“Application類”是指SpringBoot專案入口類。這個類的位置很關鍵:
如果Application類所在的包為:com.root.app,則只會掃描com.root.app包及其所有子包,如果service或dao所在包不在com.root.app及其子包下,則不會被掃描!
即, 把Application類放到dao、service所在包的上級,com.root.Application
我出問題的類確實在Application類子包下面,排除此項。 - 意識到只是攔截器(或過濾器)上會有這樣的問題,查詢原因應該是:
攔截器執行在自動bean初始化之前導致這個問題的。
Spring web中各個元素的初始化順序
在web.xml中各個元素的執行順序:
context-param–>listener–>filter–>servlet
而攔截器是在Spring MVC中配置的,如果從整個專案中看,一個servlet請求的執行過程就變成了這樣:
context-param–>listener–>filter–>servlet–>interceptor(指的是攔截器)
為什麼攔截器是在servlet執行之後,因為攔截器本身就是在servlet內部的。
元素具體概念
-
context-param:就是一些需要初始化的配置,放入context-param中,從而被監聽器(這裡特指org.springframework.web.context.ContextLoaderListener)監聽,然後載入;
-
listener(監聽器):就是對專案起到監聽的作用,它能感知到包括request(請求域),session(會話域)和applicaiton(應用程式)的初始化和屬性的變化;
-
filter(過濾器):就是對請求起到過濾的作用,它在監聽器之後,作用在servlet之前,對請求進行過濾;
-
servlet:就是對request和response進行處理的容器,它在filter之後執行,servlet其中的一部分就是controller層(標記為servlet_2),還包括渲染檢視層(標記為servlet_3)和進入controller之前系統的一些處理部分(servlet_1),另外我們把servlet開始的時刻標記為servlet_0,servlet結束的時刻標記為servlet_4。
-
interceptor(攔截器):就是對請求和返回進行攔截,它作用在servlet的內部,具體來說有三個地方:
1)servlet_1和servlet_2之間,即請求還沒有到controller層2)servlet_2和servlet_3之間,即請求走出controller層次,還沒有到渲染時圖層
3)servlet_3和servlet_4之間,即結束檢視渲染,但是還沒有到servlet的結束
解決方案
- 使用WebApplicationContext 上下文物件來手動注入
- 在專案中繼承“WebMvcConfigurerAdapter”類的類中新增攔截器類作為一個Bean(推薦)
問題原因
造成null的原因是因為攔截器載入是在springcontext建立之前完成的,所以在攔截器中注入實體自然就為null。
注入為null的時候,是通過new的方式建立的攔截器,通過new出來的例項是沒有交給spring進行管理的,沒有被spring管理的例項,spring是無法自動注入bean的,所以為null
參考連線:
- https://blog.csdn.net/ycf921244819/article/details/91388440
- https://www.cnblogs.com/shamo89/p/8534580.html
相關文章
- Spring 過濾器和攔截器Spring過濾器
- spring中的過濾器與攔截器Spring過濾器
- 解決在Interceptor攔截器中使用@DubboReference注入為nullNull
- 談談 Spring 的過濾器和攔截器Spring過濾器
- SpringBoot中的過濾器和攔截器的實現Spring Boot過濾器
- 攔截過濾器模式過濾器模式
- SpringBoot攔截器中獲取註解、攔截器中注入ServiceSpring Boot
- spring boot 新增自定義監聽器、過濾器、攔截器Spring Boot過濾器
- Spring MVC 中的攔截器的使用“攔截器基本配置” 和 “攔截器高階配置”SpringMVC
- springBoot的過濾器,監聽器,攔截器Spring Boot過濾器
- 攔截器(Interceptor)與過濾器(Filter)過濾器Filter
- SpringBoot 攔截器、過濾器、監聽器Spring Boot過濾器
- Solon 的過濾器 Filter 和兩種攔截器 Handler、 Interceptor過濾器Filter
- 監聽器,過濾器,攔截器的執行過程和對比過濾器
- 聊一聊過濾器與攔截器過濾器
- springmv的過濾器和攔截器的區別是什麼Spring過濾器
- 過濾器 Filter 與 攔截器 Interceptor 的區別過濾器Filter
- springboot系列文章之過濾器 vs 攔截器Spring Boot過濾器
- SpringBoot實現過濾器、攔截器與切片Spring Boot過濾器
- spring攔截器Spring
- 過濾器和攔截器有啥區別,這次會了!過濾器
- Spring Boot中攔截器的使用Spring Boot
- spring mvc攔截器,spring攔截器以及AOP切面的區別和原始碼SpringMVC原始碼
- Spring Boot使用過濾器和攔截器分別實現REST介面簡易安全認證Spring Boot過濾器REST
- spring boot 攔截器Spring Boot
- 極簡架構模式-攔截過濾器模式架構模式過濾器
- 解決spring cloud Feign遠端呼叫服務,新增headers解決攔截器攔截問題SpringCloudHeader
- 過濾器 和 攔截器 6 個區別,別再傻傻分不清了過濾器
- 過濾器 和 攔截器 6個區別,別再傻傻分不清了過濾器
- 過濾器、攔截器、AOP、ControllerAdvcie執行順序對比過濾器Controller
- Java Filter過濾器(攔截路徑的配置+攔截方式的配置+生命週期+多個過濾器的先後執行順序)JavaFilter過濾器
- Spring 常用的三種攔截器詳解Spring
- spring mvc 攔截器的使用SpringMVC
- 為什麼你寫的攔截器注入不了 Java bean?JavaBean
- Spring Boot新增攔截器Spring Boot
- SpringMVC中的攔截器SpringMVC
- grpc中的攔截器RPC
- 伺服器自動重啟的原因及解決方法-VeCloud伺服器Cloud