Arthas实践--获取到Spring Context,而后随心所欲

背景
Arthas 是Alibaba开源的Java诊断工具,深受开发者喜好。html

https://github.com/alibaba/ar...
Arthas提供了很是丰富的关于调用拦截的命令,好比 trace/watch/monitor/tt 。可是不少时候咱们在排查问题时,须要更多的线索,并不仅是函数的参数和返回值。
好比在一个spring应用里,想获取到spring context里的其它bean。若是能随意获取到spring bean,那就能够“随心所欲”了。git

下面介绍如何利用Arthas获取到spring context。github

Demo: https://github.com/hengyunabc...web

Arthas快速开始:https://alibaba.github.io/art...spring

使用tt命令获取到spring context
Demo是一个spring mvc应用,请求会通过一系列的spring bean处理,那么咱们能够在spring mvc的类里拦截到一些请求。mvc

启动Demo: mvn spring-boot:runapp

使用Arthas Attach成功以后,执行tt命令来记录RequestMappingHandlerAdapter#invokeHandlerMethod的请求ide

tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
而后访问一个网页: http://localhost:8080/函数

能够看到Arthas会拦截到这个调用,index是1000,而且打印出:spring-boot

$ watch com.example.demo.Test * 'params[0]@sss'
$ tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 101 ms.
INDEX TIMESTAMP COST(ms IS-RE IS-EX OBJECT CLASS METHOD

)        T      P

1000 2019-01-27 16:31 3.66744 true false 0x4465cf70 RequestMappingHandlerAda invokeHandlerMethod

:54                                                   pter

那么怎样获取到spring context?

能够用tt命令的-i参数来指定index,而且用-w参数来执行ognl表达式来获取spring context:

$ tt -i 1000 -w 'target.getApplicationContext()'
@AnnotationConfigEmbeddedWebApplicationContext[

reader=@AnnotatedBeanDefinitionReader[org.springframework.context.annotation.AnnotatedBeanDefinitionReader@35dc90ec],
scanner=@ClassPathBeanDefinitionScanner[org.springframework.context.annotation.ClassPathBeanDefinitionScanner@72078a14],
annotatedClasses=null,
basePackages=null,

]
Affect(row-cnt:1) cost in 7 ms.
从spring context里获取任意bean
获取到spring context以后,就能够获取到任意的bean了,好比获取到helloWorldService,并调用getHelloMessage()函数:

$ tt -i 1000 -w 'target.getApplicationContext().getBean("helloWorldService").getHelloMessage()'
@String[Hello World]
Affect(row-cnt:1) cost in 5 ms.
更多的思路
在不少代码里都有static函数或者static holder类,顺滕摸瓜,能够获取不少其它的对象。好比在Dubbo里经过SpringExtensionFactory获取spring context:

$ ognl '#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next, 
#context.getBean("userServiceImpl").findUser(1)'
@User[
    id=@Integer[1],
    name=@String[Deanna Borer],
]

本文做者:横云断岭

阅读原文

本文为云栖社区原创内容,未经容许不得转载。

相关文章
相关标签/搜索