Arthas实践--获取到Spring Context,然后为所欲为
首页 > 后端开发    作者:StanWind   2021年11月4日 17:04 星期四   热度:301°   百度已收录  
时间:2021-11-4 17:04   热度:301° 

背景

Arthas 是Alibaba开源的Java诊断工具,深受开发者喜爱。

Arthas提供了非常丰富的关于调用拦截的命令,比如 trace/watch/monitor/tt 。但是很多时候我们在排查问题时,需要更多的线索,并不只是函数的参数和返回值。
比如在一个spring应用里,想获取到spring context里的其它bean。如果能随意获取到spring bean,那就可以“为所欲为”了。

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

Demo: https://github.com/hengyunabc/spring-boot-inside/tree/master/demo-arthas-spring-boot

Arthas快速开始:https://alibaba.github.io/arthas/quick-start.html

使用tt命令获取到spring context

Demo是一个spring mvc应用,请求会经过一系列的spring bean处理,那么我们可以在spring mvc的类里拦截到一些请求。

启动Demo: mvn spring-boot:run

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

1 
tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod 

然后访问一个网页: http://localhost:8080/

可以看到Arthas会拦截到这个调用,index是1000,并且打印出:

1 2 3 4 5 6 7 8 9 
$ 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:

1 2 3 4 5 6 7 8 
$ 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()函数:

1 2 3 
$ 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:

1 2 3 4 5 6 
$ 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], ] 

链接


二维码加载中...
本文作者:StanWind      文章标题: Arthas实践--获取到Spring Context,然后为所欲为
本文地址:https://www.stanwind.com/post/80
版权声明:若无注明,本文皆为“Make it Better”原创,转载请保留文章出处。

返回顶部    首页    手机版本    后花园  
版权所有:Make it Better    站长: StanWind    赣ICP备17014296号   360网站安全检测平台  
00:00 / 00:00
随机播放