dubbo debug過程當中一個有趣的問題

最近在debug dubbo代碼過程當中遇到的頗有趣的問題

咱們都知道dubbo ReferenceBean是消費者的spring bean包裝,爲了查一個consumer端的問題,在ReferenceBean的父類ReferenceConfig的 T get()方法(140行)打上了一個斷點。

當我debug 跟進init方法以後發現,ReferenceConfig的成員變量initialized(boolean類型),沒有初始化,值變成了true? 納尼。。。
在學習java的基礎知識的時候,咱們就知道若是boolean類型若是不初始化變量,運行的時候默認初始爲true。爲何變量initialized沒有賦值的狀況,值是true呢?
java

更奇怪的是,debug模式下,由於initialized=true consumer的樁代碼(proxy)沒有生成,因此在業務層調用的時候跑出了NPE;可是在run模式下是對的。git

初步懷疑

初步懷疑是debug模式和run模式下初始化的值是不一樣的,而後上google去搜索一下是否是存在這個問題,惋惜沒有任何的收穫;同時在初始化的時候,直接把initialized初始化爲false,防止缺省值初始成true。
可是問題依舊,放棄了這條思路!!!
而後開始懷疑是IDEA編輯器是否是在斷點處有setvalue的狀況,就把IDEA所有緩存清空並重啓了(File->Invalidate....),debug後問題依然!!!github

修改dubbo的源代碼加日誌輸出

實在沒什麼思路了,想着先去增長一些日誌輸出,辦法雖然很土,可是可能會有線索。在initialized=true 這行代碼以後加一行輸出
System.out.println("init initialized="+initialized);

同時斷點還在ReferenceConfig.get()方法裏面
spring

當運行到斷點出,觀察console的輸出,果真有輸出!!!!
apache

這說明當我斷點在ReferenceConfig.get()方法裏時候,有線程執行了init()方法致使initialized的值被修改爲了true(dubbo代碼只有一處修改ReferenceConfig.initialized值的地方,就在init裏面)
因此只要找出哪一個線程在我斷點的時候,執行了init方法就好了api

日誌輸出又立大功

繼續在init方法裏面加日誌輸出,如下日誌能顯示出哪一個堆棧調用了init方法
緩存

繼續debug運行,獲得結果出乎意外
編輯器

從日誌輸出能夠看出來,在ReferenceConfig構造函數的地方,調用了父類AbstractConfig.toString方法,而在AbstractConfig的toString方法裏面反射間接調用了ReferenceConfig.init()方法
這下算是找到誰在我斷點的時候調用了ReferenceConfig.init()方法,就是toString()方法。
可是誰調用了toString()方法呢?函數

真想大白

首先能夠排除程序在構造函數裏面調用AbstractConfig.toString方法,還有一種可能就是IDEA 爲了顯示觸發了這個類實例的toString方法。有了這個假設思路,寫了一個demo驗證一下學習

果不其然console裏面輸出了invoke toString()

總結

IDEA 這類編輯器帶debug功能爲了斷點處能顯示一個類的實例,就會反射調用實例的toString!!!!
真是一個有趣的發現!!!!

附送dubbo ReferenceConfig源碼連接

相關文章
相關標籤/搜索