對基於spring的工程而言,獲取到spring上下文就可以做很多事情,比如獲取註冊的Bean對象,查看其屬性值,調用其方法等。生產環境中排查問題時,不方便修改代碼打印變量的值、重啓服務以便調用刷新緩存的方法等,這時,使用arthas就方法許多了。
基於SpringMvc的工程
- 獲取spring上下文
tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod -n 3
- 獲取Bean對象
tt -i 1000 -w 'target.getApplicationContext().getBean("serviceBTRelationServiceImpl")'
- 如果Bean是AOP代理後的對象,如何獲取目標對象呢
tt -i 1000 -w 'target.getApplicationContext().getBean("serviceBTRelationServiceImpl").getTargetSource()'
- 獲取目標對象
tt -i 1000 -w 'target.getApplicationContext().getBean("serviceBTRelationServiceImpl").getTargetSource().target'
- 執行目標對象屬性或方法
tt -i 1000 -w 'target.getApplicationContext().getBean("serviceBTRelationServiceImpl").getTargetSource().target.cacheMap'
基於Dubbo的工程
ognl 語法
- 靜態方法 @System@getProperties(“java”)
- 普通對象 #userService.get(“id”)
在Dubbo裏有一個擴展com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory,把Spring Context保存到了裏面。 因此,我們可以通過ognl命令獲取到。
- 查詢類加載信息,這裏使用類加載器的hash
sc -d 'com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory'
- 獲取spring上下文
ognl -c 5197848c '#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next'
- 使用spring上下文獲取業務對象
ognl -c 5197848c '#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next, #context.getBean("tianqiRedisFactory").jedisPools' -x 3