【arthas】 arthas命令记录
一.下载安装arthas
wget https://alibaba.github.io/arthas/arthas-boot.jar
二.启动,退出,停止
1.启动方法
java -jar arthas-boot.jar
2.退出当前指定的某一个arthas的命令
Q 或者 Ctrl+C
3.退出arthas[只能退出当前会话,arthas server并未停止执行]
exit 或者 quit
退出后可以通过 java -jar arthas-boot.jar 重连 arthas server服务
4.完全退出arthas server
使用 stop
5.仪表盘
dashboard
堆内存信息
heap 堆内存
ps_eden_space : 对象被创建的时候首先存放的区域
ps_survivor_space : eden space内存区域中经过垃圾回收后没有被回收的对象
ps_old_gen: 存放新生代中经过多次垃圾回收仍然存活的对象(上面两个都是新生代)
nonheap: 非堆内存(通常说的栈内存)
code_cash: 存放JIT所编译的机器码
metaspace: 永久代
三.trace使用,查看方法内一级子方法调用耗时【往下的调用链路】
1.基础使用示例:【也可以看出来整个调用栈中哪行抛出异常了throws Exception】
trace 类路径 方法名
trace com.test.ClassA methodB
2.如果本方法调用次数很多,则只想捕获10次 的调用 就退出Q
trace 类路径 方法名 run -n 10
3.tracem默认不展示JDK方法调用耗时,如果想打印出来,需要显式设置 --skipJDKMethod false
trace --skipJDKMethod false 类路径 方法名
4.匹配多个类或多个函数
trace -E com.test.ClassA|org.test.ClassB method1|method2|method3
5.排查时间大于2ms的调用
trace com.test.ClassA methodB '#cost > 2'
6.监听该方法 入参的invokeSysName属性 传入是"price-test"字符串时候的 1000次调用
trace com.test.ClassA methodB -n 1000 'params[0].getInvokeSysName().equals("price-test")'
7.监听该方法 入参的invokeSysName属性 传入是"Press-Test"字符串时候的 AND 响应时间>50ms的 1000次调用
trace com.test.ClassA methodB -n 1000 'params[0].getInvokeSysName().equals("Press-Test") && #cost > 50 '
四.stack使用,查看方法被调用的 调用链 【往上的调用链路】
1.基本使用示例:
stack com.test.ClassA methodB
五. 反编译
1. 查看具体 某个线程的 调用堆栈
thread PID
2.查看源码
查看某个类的源码
jad com.test.ClassA
查看某个类某个方法的源码
jad com.test.ClassA 方法A
3.只查看源码
jad --source-only com.test.ClassA
4.
六.查看具体函数
1.基础使用示例:
sm com.test.ClassA
sm com.test.ClassA methodA
2.查看某个函数的详细信息 加上属性 -d
sm -d com.test.ClassA methodA
七.查看JVM已经加载的类信息
1.具体某个类的JVM加载信息 【如果它是接口,还会把实现类打印出来】
sc -d com.test.ClassA
2.正则匹配JVM加载类的信息
sc -d com.test.Class*
或者
sc -d com.test.*B
八.动态实时监控接口
1.动态实时监控接口出入参和异常信息 层级是3层,捞取5次请求
watch com.test.ClassA methodA '{params,returnObj,throwExp}' -v -n 5 -x 3 '1==1'
2.同上,但是指定入参的第二个参数等于true的
watch com.test.ClassA methodA '{params,returnObj,throwExp}' 'params[1] == true' -v -n 5 -x 3 '1==1'
3.查看的stuId值(独立展示想要看的具体的值)
现在请求入参是个StuQuery
class StuQuery{
private Integer stuId;
}
watch com.test.ClassA methodA '{params,returnObj,throwExp,params[0].{#this.stuId}[0]}' -v -n 5 -x 3 '1==1'
4.仅查看 入参的stuId == 2109241013000001L(Long需要转型)(仅watch 指定想要看的请求 修改表达式)
watch com.test.ClassA methodA '{params,returnObj,throwExp}' -v -n 5 -x 3 'params[0].{#this.stuId}[0].equals(2109241013000001L)'
5.当watch 设置-x层级依旧看不到对象中对象的属性时,可以自己指定返回查看的属性,例如指定查看返回对象的joinItems属性的集合中的第一个对象的zoneItems属性
watch com.test.ClassA methodA '{params,returnObj,throwExp,returnObj.joinItems[0].zoneItems}' -v -n 5 -x 3 '1==1'
6.查找上游请求从哪里请求进来的
watch -x 2 com.test.ClassA methodA '#appCode=@org.apache.dubbo.rpc.utils.UpStreamUtil@getRemoteAppCode(),
#r_code=@org.apache.dubbo.rpc.utils.UpStreamUtil@getRemoteProCode(),#traceId=@com.XXX.monitor.sdk.Monitor@getTraceId(),{#appCode,#r_code,#traceId,params}' 'params[0].venderId==1'
7.实时查看运行到当前方法所在类的对象 中的具体某个属性值
例如查看仅当params的field222=1000 时候的 当前对象的field111属性值是多少
watch com.test.ClassA methodA '{params,target.field111 }' "params[0].field222=1000" -n 5 -x 5
8.
九.查看类的静态成员变量
1.查看类的静态成员变量 层级是3层
getstatic com.test.ClassA staticA -x 3
十.查看某个Spring管理的Bean的属性值
1.监听到拦截器请求的一个下标,得到一个数字
tt -t -n 1 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
2.使用得到的下标进行替换,从上下文中获取到该Bean,就可以执行该Bean的方法了
用得到的数字替换1002,taskExecutor就是bean的name, getBean("taskExecutor")之后就可以.该Bean提供的方法,或者直接查看该Bean的属性值
taskExecutor 是举例的一个Bean的name,可以是xxx,也可以是你自己的Bean的name
tt -i 1002 -w 'target.getApplicationContext().getBean("taskExecutor").getThreadPoolExecutor().getQueue().size()'
3.或者直接查看该Bean的属性值,查看3层
tt -i 1002 -w 'target.getApplicationContext().getBean("taskExecutor")' -x 3
十一.使用vmtool查看某个Spring管理的Bean的属性值
如下使用示例,可以一层一层属性探查到你想看到的Bean当前的属性值
用于查探 数据库Bean ,排查连接的服务器IP、端口等都非常方便
[arthas@1]$ vmtool -a getInstances --className com.XXX.ware.depotinventory.dao.util.RedisUtil -x 1
@RedisUtil[][
@RedisUtil[com.XXX.ware.depotinventory.dao.util.RedisUtil@6514dfe1],
@RedisUtil[com.XXX.ware.depotinventory.dao.util.RedisUtil@69c8da78],
]
[arthas@1]$ vmtool -a getInstances --className com.XXX.ware.depotinventory.dao.util.RedisUtil -x 2
@RedisUtil[][
@RedisUtil[
log=@Logger[Logger[com.XXX.ware.depotinventory.dao.util.RedisUtil]],
xstream=@XStream[com.thoughtworks.xstream.XStream@36ebd910],
jedisPool=@JedisPool[redis.clients.jedis.JedisPool@dc12bb1],
use=@Boolean[true],
defaultExpireTime=@Integer[1800],
],
@RedisUtil[
log=@Logger[Logger[com.XXX.ware.depotinventory.dao.util.RedisUtil]],
xstream=@XStream[com.thoughtworks.xstream.XStream@36ebd910],
jedisPool=@JedisPool[redis.clients.jedis.JedisPool@398d443b],
use=@Boolean[true],
defaultExpireTime=@Integer[1800],
],
]
[arthas@1]$ vmtool -a getInstances --className com.XXX.ware.depotinventory.dao.util.RedisUtil -x 2 --express 'instances[0].jedisPool'
@JedisPool[
internalPool=@GenericObjectPool[
factoryType=null,
maxIdle=@Integer[20],
minIdle=@Integer[0],
factory=@JedisFactory[redis.clients.jedis.JedisFactory@38344c1e],
allObjects=@ConcurrentHashMap[isEmpty=false;size=10],
createCount=@AtomicLong[10],
idleObjects=@LinkedBlockingDeque[isEmpty=false;size=10],
ONAME_BASE=@String[org.apache.commons.pool2:type=GenericObjectPool,name=],
abandonedConfig=null,
MEAN_TIMING_STATS_CACHE_SIZE=@Integer[100],
maxTotal=@Integer[100],
blockWhenExhausted=@Boolean[true],
maxWaitMillis=@Long[5000],
lifo=@Boolean[true],
fairness=@Boolean[false],
testOnCreate=@Boolean[false],
testOnBorrow=@Boolean[true],
testOnReturn=@Boolean[true],
testWhileIdle=@Boolean[true],
timeBetweenEvictionRunsMillis=@Long[30000],
numTestsPerEvictionRun=@Integer[-1],
minEvictableIdleTimeMillis=@Long[60000],
softMinEvictableIdleTimeMillis=@Long[1800000],
evictionPolicy=@DefaultEvictionPolicy[org.apache.commons.pool2.impl.DefaultEvictionPolicy@637662b4],
closeLock=@Object[java.lang.Object@25a3d43c],
closed=@Boolean[false],
evictionLock=@Object[java.lang.Object@60a9d43e],
evictor=@Evictor[org.apache.commons.pool2.impl.BaseGenericObjectPool$Evictor@7a672089],
evictionIterator=@DescendingItr[org.apache.commons.pool2.impl.LinkedBlockingDeque$DescendingItr@3fcb83d6],
factoryClassLoader=@WeakReference[java.lang.ref.WeakReference@7ceb9fce],
oname=@ObjectName[org.apache.commons.pool2:type=GenericObjectPool,name=pool],
creationStackTrace=@String[java.lang.Exception\n at org.apache.commons.pool2.impl.BaseGenericObjectPool.<init>(BaseGenericObjectPool.java:138)\n at org.apache.commons.pool2.impl.GenericObjectPool.<init>(GenericObjectPool.java:107)\n at redis.clients.util.Pool.initPool(Pool.java:43)\n at redis.clients.util.Pool.<init>(Pool.java:31)\n at redis.clients.jedis.JedisPool.<init>(JedisPool.java:73)\n at redis.clients.jedis.JedisPool.<init>(JedisPool.java:54)\n at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)\n at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)\n at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)\n at java.lang.reflect.Constructor.newInstance(Constructor.java:423)\n at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)\n at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:121)\n at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:277)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1077)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:981)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:487)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)\n at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)\n at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)\n at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)\n at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)\n at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)\n at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:108)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1419)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1160)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)\n at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)\n at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)\n at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)\n at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)\n at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:449)\n at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:423)\n at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:551)\n at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169)\n at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)\n at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:304)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1148)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)\n at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)\n at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)\n at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)\n at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)\n at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:449)\n at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:423)\n at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:551)\n at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169)\n at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)\n at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:304)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1148)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)\n at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)\n at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)\n at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)\n at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)\n at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:449)\n at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:423)\n at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:551)\n at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:169)\n at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:88)\n at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessPropertyValues(CommonAnnotationBeanPostProcessor.java:304)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1148)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)\n at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)\n at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)\n at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)\n at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)\n at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:191)\n at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:636)\n at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:934)\n at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)\n at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)\n at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:602)\n at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)\n at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:521)\n at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:462)\n at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)\n at javax.servlet.GenericServlet.init(GenericServlet.java:158)\n at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1132)\n at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1079)\n at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:973)\n at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4885)\n at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5199)\n at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)\n at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:743)\n at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:719)\n at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:714)\n at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1125)\n at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1859)\n at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)\n at java.util.concurrent.FutureTask.run(FutureTask.java:266)\n at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)\n at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)\n at java.lang.Thread.run(Thread.java:750)\n],
borrowedCount=@AtomicLong[9472],
returnedCount=@AtomicLong[9472],
createdCount=@AtomicLong[10],
destroyedCount=@AtomicLong[0],
destroyedByEvictorCount=@AtomicLong[0],
destroyedByBorrowValidationCount=@AtomicLong[0],
activeTimes=@StatsStore[org.apache.commons.pool2.impl.BaseGenericObjectPool$StatsStore@724437f6],
idleTimes=@StatsStore[org.apache.commons.pool2.impl.BaseGenericObjectPool$StatsStore@e3a8efa],
waitTimes=@StatsStore[org.apache.commons.pool2.impl.BaseGenericObjectPool$StatsStore@6d0c79d8],
maxBorrowWaitTimeMillis=@AtomicLong[159],
swallowedExceptionListener=null,
],
]
[arthas@1]$ vmtool -a getInstances --className com.XXX.ware.depotinventory.dao.util.RedisUtil -x 2 --express 'instances[0].jedisPool.internalPool.factory'
@JedisFactory[
hostAndPort=@AtomicReference[
serialVersionUID=@Long[-1848883965231344442],
unsafe=@Unsafe[sun.misc.Unsafe@4a7f9a4c],
valueOffset=@Long[12],
value=@HostAndPort[10.33.32.174:7017],
],
timeout=@Integer[2000],
password=@String[rpass7017],
database=@Integer[0],
clientName=null,
]
[arthas@1]$ vmtool -a getInstances --className com.XXX.ware.depotinventory.dao.util.RedisUtil -x 2 --express 'instances[1].jedisPool.internalPool.factory'
@JedisFactory[
hostAndPort=@AtomicReference[
serialVersionUID=@Long[-1848883965231344442],
unsafe=@Unsafe[sun.misc.Unsafe@4a7f9a4c],
valueOffset=@Long[12],
value=@HostAndPort[10.33.32.174:7017],
],
timeout=@Integer[2000],
password=@String[rpass7017],
database=@Integer[0],
clientName=null,
]
十二.getstatic 查看 某个静态属性
1.例如查看SendXXXUtil类的 client这个静态属性
getstatic com.XXX.XXX.msg.util.SendXXXUtil client
2.例如查看SendXXXUtil类的 所有静态属性
getstatic com.XXX.XXX.msg.util.SendXXXUtil *
十三.使用sc+vmtool 或 sc+ognl 完成实时调用某个Bean的方法
假如有一个Bean这样定义
@Controller
@RequestMapping("/manual")
public class Manual3Controller {
@ResponseBody
@RequestMapping(value = "/forceFixInventory")
public Message forceFixInventory(Integer shopId, @RequestParam(value = "skuIds", required = false) List<Long> skuIds) {
...
}
}
方法1: sc+vmtool (已测通)
第一步,使用sc查看指定Bean的类加载器Hash
sc -d com.XXX.ware.depotinventory.dashboard.controller.Manual3Controller
第二步,使用vmtool查看这个Bean
vmtool --action getInstances -c 3f9cc5c7 --className org.springframework.context.ApplicationContext --express 'instances[0].getBean("manual3Controller")' -x 3
第三步,使用vmtool调用这个Bean的方法
vmtool --action getInstances -c 3f9cc5c7 --className com.XXX.ware.depotinventory.dashboard.controller.Manual3Controller --express 'instances[0].forceFixInventory(642,null)' -x 3
方法2:sc+ognl (未测通)
此方法适用于你的项目中有此种自定义的Util定义
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
public static Object getBean(String beanName) {
return applicationContext.getBean(beanName);
}
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
}
第一步: 使用sc查找这个Util的 类加载器Hash
sc -d *SpringContextUtil | grep classLoaderHash
第二步: 指定类加载器,通过util找到Bean,并执行Bean的方法
ognl -c 3f9cc5c7 '@com.XXXutil.SpringContextUtil@getBean("manual3Controller").forceFixInventory(642, null)'