記錄一個不易被發現的代碼問題:原本一個運行正常的項目 , 最近出現一個奇怪的問題 。 在某個Controller的方法中 , 使用的某些@autowired注入的bean值變成了null 。詭異的是 , 同樣的bean在其他Controller中 , 甚至在當前Controller的其他方法中 , 都一切如常。
經過問題排查,分析原因,發現這些方法在某次feature后加入了aop切面做日志分析,於是查看相關修改涉及到的出現類似問題的方法修飾符,都是private修飾的方法 。
解釋一下原因:
Spring的aop機制使用的是jdk自身的動態代理機制或者cglib的代理機制實現,分別基於接口和子類繼承機制實現。
再具體到 spring aop部分的源碼
Method[] methods = clazz.getMethods();
用JAVA反射的方式獲取也只能拿到public/protected方法,所以private方法無法被代理 , 最終導致bean注入失敗。
綜上,這其實是個很簡單的問題,但是在舊項目改造這類場景中會出現而且不容易發現的問題,開發人員往往執念於未對原方法邏輯有任何改動而忽略掉。使用新加入的切面要確認目標方法的修飾符不為private。