任何花费了比较多时间,经过思考才解决的问题,都值得记录一下。方便日后查阅,也方便别人参考。
背景
在Arthas
中,我们通过tt
命令,是可以调用任意非静态函数,例如:
tt -i 1000 -w 'target.getApplicationContext().getBean("remoteEventService").queryGroupFantasyDataByGroupId(200017000L)'
或者像这样:
tt -i 1000 -w 'target.getApplicationContext().getBeansOfType(@com.event.api.EventApi@class).queryEventById(200017000L, @com.alibet.fantasy.center.dto.Event@class)'
但是,上面的例子中,参数是比较简单的,
200017000L 是一个简单的Long类型,
@com.alibet.fantasy.center.dto.Event@class 是ognl表达式,获取的是一个静态的对象。
那么对于更复杂一点的情况,例如用一个类对象做参数应该如何实现呢?
ognl创建对象做参数
经过实验之后,通过ognl
表达式是可以实现的:
tt -i 1000 -w 'target.getApplicationContext().getBean("eventServiceImpl").convertNewEventVO((#value1=new com.alibet.fantasy.center.vo.EventVO(),#value1.setEventId(123L),{#value1})[0])'
这里面有两个比较trick的地方需要解释一下:
#value1=new com.alibet.fantasy.center.vo.EventVO(),#value1.setEventId(123L),{#value1}
是一个ognl表达式,意义很简单,new一个对象,然后设置某些属性。这个表达式本身没什么问题,如果把它作为一个参数,就需要用小括号括起来,否则函数调用就根据逗号分隔,把表达式作为3个参数来处理。
第二个trick的地方是需要在小括号外面取第0个元素。
原因是Arthas
解析时,把小括号当做了数组。
了解了这两个trick,就可以使用ognl表达式来构建任意对象,作为参数传递给需要的地方。
转载请注明:牛哥678 » Arthas调用任意函数时,使用ognl创建对象做参数