本文主要是介绍arthas使用ognl修改线上动态对象(实例)的属性值,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
线上我们某个业务功能有个开关没有打开。需要在不重启服务的情况下把isOpen这个值变成true
arthas是一个很好的工具。用它修改静态的变量非常方便,但是动态的就有点麻烦了。不过也是可以实现的。
原理:
1、首先从spring容器中拿到LedgerTimer类的实例
2、使用反射找到LedgerTimer类的isOpen字段
3、通过反射修改isOpen字段的值
具体做法:
1、首先启动arthas连接上我们的服务,这里不再赘述。
Arthas - Java 线上问题定位处理的终极利器_程序猿阿朗的博客-CSDN博客
2、执行下面的代码(使用ognl命令)
ognl --classLoaderClass org.apache.catalina.loader.WebappClassLoader'#instence=@cn.com.maxtech.util.Maxtech@me.getBean("LedgerTimer"),
#fieldObj=@cn.com.maxtech.jswyj.ledger.timer.LedgerTimer@class.getDeclaredField("isOpen"),
#fieldObj.setAccessible(true),
#fieldObj.set(#instence,true)'
参数解释:
1、--classLoaderClass org.apache.catalina.loader.WebappClassLoader 指定classload为tomcat的webappClassLoader(因为我们的springboot项目使用的外置tomcat)(必须添加classLoader参数,如不清楚可以arthas执行classloader命令查看)
2、#instence=@cn.com.maxtech.util.Maxtech@me.getBean("LedgerTimer") 从spring容器中拿到LedgerTimer类的实例放入一个变量instence中
3、#fieldObj=@cn.com.maxtech.jswyj.ledger.timer.LedgerTimer@class.getDeclaredField("isOpen") 使用反射获取LedgerTimer类的isOpen字段对象放入fieldObj变量中
4、#fieldObj.setAccessible(true) 由于isOpen字段没有设置public访问权限,所以需要执行此段代码放开访问权限
5、#fieldObj.set(#instence,true) 修改字段值
Maxtech类如下。主要是为了保存BeanFactory
public class Maxtech {private static Maxtech me = null;BeanFactory tempContext = null;private Maxtech() {}public static Maxtech getInstance() {if (me == null) {me = new Maxtech();}return me;}public void setAppContext(BeanFactory context) {this.tempContext = context;}public Object getBean(String name) {return this.tempContext.getBean(name);}public BeanFactory getAppContext() {return this.tempContext;}
}
从spring容器中获取bean方式有很多种。可以参考从Spring容器中获取bean的几种方式_spring从容器中获取bean_我家有个艳的博客-CSDN博客
3、查看修改结果,由于isOpen使用的boolean类型变量所以使用getBoolean命令
提示:@Boolean[true] ,表示修改完成
其他:
如果要修改的变量为String,也和上面一样,例如修改passward字段
先查询一下password的值
再修改成111222333444555666
查看结果
已修改完毕
这篇关于arthas使用ognl修改线上动态对象(实例)的属性值的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!