获得ApplicationContext为所欲为
通过Arthas获得ApplicationContext的方法有多种,在特定的项目中使用适合的方式实现。
考虑通过vmtool实现,vmtool可以查询内存对象,通过这个特点, 可以直接指定类名称获得其实例列表,选取合适的实例即可。
# 获得ApplicationContext
vmtool -a getInstances --className org.springframework.context.ApplicationContext \
--express "#ctx=instances[0], #bean=#ctx.getBean(@com.xxx.xxx.XxxBean@class),#bean.doSomething()"
# 既然都能获得ApplicationContext 我直接获取目标对象不香嘛?
[arthas@3716]$ vmtool -a getInstances --className com.xxx.xxx.system.application.service.UserService
@UserService[][
@UserService$$EnhancerBySpringCGLIB$$5af3ff3a[com.xxx.xxx.system.application.service.UserService@49f20b8c],
@UserService[com.xxx.xxx.system.application.service.UserService@49f20b8c],
]
# 拿到代理对象为所欲为
[arthas@3716]$ vmtool -a getInstances --className com.xxx.xxx.system.application.service.UserServic \
--express "instances[0].doSomething()"
提示
还有一些其他的方法获得ApplicationContext,个人觉得比vmtool实现更复杂,参考
- 若存在ApplicationContext持有的Holder工具类,通过ognl表达式静态方法获得
- 通过tt命令,通过时间片段ognl表达式获得target实例的context属性