javascript
Spring 拦截器和过滤器中自动注入为 null 的原因及解决方案
起因
開發過程中在過濾器(filter)中注入Bean出現空指針異常,通過查找資料了解空指針的原因,特此記錄。
問題分析
由于其他bean在service,controller層注入一點問題也沒有,開始根本沒意識到Bean無法注入是在攔截器中無效的問題。
“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的結束
解決方案
問題原因
造成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 拦截器和过滤器中自动注入为 null 的原因及解决方案的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 狗头ap上单符文天赋(ap狗头天赋符文怎
- 下一篇: 实现简单的注解型MVC框架 —— 低配S