1. ognl获取bean

SpringContextUtil,通常代码中会有类似这样的工具类用来获取 bean 实例

@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);
}
}

UserController

@RestController
public class UserController { private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class); @GetMapping("/user/{id}")
public User getUser(@PathVariable Integer id) { if (null == id) {
throw new IllegalArgumentException("id can not be null");
}
if (id < 1) {
throw new IllegalArgumentException("id must be greater than 1");
} return new User(id, "zhangsan");
}
}

使用 arthas 连接 spring 应用,执行如下操作:

  1. 查找全类名

    sc *SpringContextUtil
  2. 查找类加载器

    sc -d *SpringContextUtil | grep classLoaderHash
  3. 使用ognl表达式获取bean,并调用方法

    > ognl -c 18b4aac2 '@com.soulballad.usage.arthasdemo.util.SpringContextUtil@getBean("userController").getUser(2)'

2. watch观测方法调用

# 查看 UserController 下所有方法的 参数、对象、返回值
watch com.soulballad.usage.arthasdemo.web.UserController * '{params,target,returnObj}'

watch 支持方法调用前、调用后、异常抛出等多个场景观测,同时还可以在第四个参数中使用条件进行过滤,比如:

watch com.soulballad.usage.arthasdemo.web.UserController * '{returnObj}' 'params[0]>10'
watch com.soulballad.usage.arthasdemo.web.UserController * '{returnObj}' '#cost>10'

3. 热更新

步骤:使用jad反编译 -> 修改文件 -> 使用mc重新编译修改后的文件->使用redefine加载重新编译后的类

上述 UserController 访问 user/0,会出现如下错误:

There was an unexpected error (type=Internal Server Error, status=500).

id must be greater than 1

现对其进行热更新

  1. 反编译 UserController

    # --source-only 只输出源码
    jad --source-only com.soulballad.usage.arthasdemo.web.UserController > UserController.java
  2. 修改编译后的文件

    package com.soulballad.usage.arthasdemo.web;
    
    import com.soulballad.usage.arthasdemo.model.User;
    import com.soulballad.usage.arthasdemo.util.SpringContextUtil;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RestController; @RestController
    public class UserController {
    private static final Logger LOGGER = LoggerFactory.getLogger(UserController.class); @GetMapping(value={"/user/{id}"})
    public User getUser(@PathVariable Integer id) {
    if (null == id) {
    throw new IllegalArgumentException("id can not be null");
    }
    if (id < 1) {
    // throw new IllegalArgumentException("id must be greater than 1");
    return new User(id, "lisi"+id);
    }
    return new User(id, "zhangsan");
    }
    }
  3. 重新编译

    # 使用mc重新编译修改后的文件,这里需要使用 -c 指定类加载器
    sc -d com.soulballad.usage.arthasdemo.web.UserController | grep classLoaderHash
    mc -c 18b4aac2 UserController.java

    编译完成会出现一个路径,这个路径就是编译后class文件的位置

  4. 使用redefine重新加载

    # redefine 后面使用上一步的路径,需要将 \ 转成 /
    redefine ../UserController.class

  5. 更新后结果

4. 更新日志级别

查找类加载器

sc -d *UserController | grep classLoaderHas

查看更新前日志级别

ognl -c 18b4aac2 '@com.soulballad.usage.arthasdemo.web.UserController@LOGGER'

更新日志级别为 DEBUG

ognl -c 18b4aac2 '@com.soulballad.usage.arthasdemo.web.UserController@LOGGER.setLevel(@ch.qos.logback.classic.Level@DEBUG)'

查看更新后日志级别

5. tt获取spring上下文

执行 tt 命令来记录 RequestMappingHandlerAdapter#invokeHandlerMethod 的请求

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

然后访问 user/1,arthas 会记录访问时间片(time fragment)

可以用 tt 命令的 -i 参数来指定index,并且用 -w 参数来执行ognl表达式来获取spring context:

tt -i 1000 -w 'target.getApplicationContext()'

可以从 applicationContext 中获取 bean,触发方法调用

tt -i 1000 -w 'target.getApplicationContext().getBean("userController").getUser(2)'

6. 链接

Arthas 使用(二) —— 应用场景的更多相关文章

  1. 【Unity】实验二 游戏场景搭建

    实验要求 实验二 游戏场景搭建 实验目的:掌握游戏场景搭建. 实验要求:能够使用Unity的地形引擎创建地形,熟悉场景中的光照与阴影,掌握天空盒和雾化效果等. 实验内容: 地形的绘制:使用高度图绘制: ...

  2. Qt开发技术:图形视图框架(二)场景QGraphicsScene、QGraphicsItem与QGraphicsView详解

    前话   Qt的图形视图框架,最核心的三个类为:QGraphicsScene.QGraphicsItem与QGraphicsView.   基于图形框架的高级白板软件Demo QGraphicsSce ...

  3. 【英宝通Unity4.0公开课学习 】(二)场景创建

    本讲共四节,貌似讲课老师的速度变快了,2倍速听不清了...调成了1.7倍...老师果然越来越熟练了啊! 而且最开始的萌妹纸也不再出现在视频里了,我当时还想着完全可以换成老师自己提问嘛! 不过有妹纸声音 ...

  4. LoadRunner测试场景中添加负载生成器

    如何在LoadRunner测试场景中添加负载生成器 本文对如何在LoadRunner的测试场景中添加负载生成器,如何使用负载生成器的方法,总结形成操作指导手册,以指导测试人员指导开展相关工作. 1.什 ...

  5. scrapy 的三个入门应用场景

    说明: 本文参照了官网的 dmoz 爬虫例子. 不过这个例子有些年头了,而 dmoz.org 的网页结构已经不同以前.所以我对xpath也相应地进行了修改. 概要: 本文提出了scrapy 的三个入门 ...

  6. ARPG客户端中场景对象体系设计

    一.场景对象体系 二.场景对象生命周期管理 场景对象的生命周期,不适合采用原始的c++管理方式, 即由使用者自己负责删除.而应该采用引用计数方式, 自动负责删除. 采用引用计数方式, 目前用法比较广的 ...

  7. 3D场景优化

    一) 有效的性能评测 对于任何一个3D应用程序来说,追求场景画面真实感是一个无止尽的目标,其结果就是让我们的场景越来越复杂,模型更加精细,这必然给图形硬件带来极大的负荷以致于无法达到实时绘制帧率.因此 ...

  8. Numpy中Meshgrid函数介绍及2种应用场景

    近期在好几个地方都看到meshgrid的使用,虽然之前也注意到meshgrid的用法.但总觉得印象不深刻,不是太了解meshgrid的应用场景.所以,本文将进一步介绍Numpy中meshgrid的用法 ...

  9. PhiloGL学习(1)——场景创建及方块欲露还羞出水面

    前言 上一篇文章中介绍了我认识PhiloGL框架的机缘以及初步的探讨(见JS前端三维地球渲染--中国各城市航空路线展示),在此文中仅仅对此框架进行了简单介绍并初步介绍了一些该框架的知识.首先三维这个东 ...

随机推荐

  1. mysql5.7免安装版配置

    解压之后,新建一个my.ini 内容是: [mysql] # 设置mysql客户端默认字符集 default-character-set = utf8 [mysqld] #安装目录 basedir = ...

  2. sort()实现排序的原理

    很多人都只知道sort()是通过快速排序实现,但它并不只是简单的快排:首先它对普通的快速排序进行了优化:此外,它还结合了插入 排序和堆排序.系统根据数据形式和数据量,来选择合适的排序方法,这并不是说每 ...

  3. Async,Await 深入源码解析

    1.同步与异步 假设存在 IO事件A:请求网络资源 (完成耗时5s) IO事件B:查询数据库 (完成耗时5s) 情况一:线程1工人在发起A请求后,一直阻塞等待,在A响应返回结果后再接着处理事件B,那总 ...

  4. thinkphp5.1+ 使用 Redis 缓存

    修改 config/cache.php 将其配置成多个缓存类型,示例 <?php // +---------------------------------------------------- ...

  5. 【java基础】01 计算机基础知识

    一.计算机基础知识 1. 计算机 1. 什么是计算机? 计算机在生活中的应用举例 计算机(Computer)全称:电子计算机,俗称电脑.是一种能够按照程序运行,自动.高速处理海量数据的现代化智能电子设 ...

  6. 【linux三剑客】grep命令

    grep, egrep, fgrep - print lines matching a pattern grep 命令用于查找文件里符合条件的字符串. grep 指令用于查找内容包含指定的范本样式的文 ...

  7. RMI原理揭秘之远程对象

    讨论开始之前,我们先看看网上的一个例子,这个例子我腾抄了一分,没有用链接的方式,只是为了让大家看得方便,如有侵权,我立马***. 定义远程接口: 1 2 3 4 5 6 package com.guo ...

  8. java的基础知识01

    来自<head first java>书籍的摘录

  9. 一只简单的网络爬虫(基于linux C/C++)————主事件流程

    该爬虫的主事件流程大致如下: 1.获取命令行参数,执行相应操作 2.读取配置文件,解析得到各种设置 3.载入各种模块 4.种子入队,开启DNS解析线程(原始队列不为空时解析) 5.创建epoll,开启 ...

  10. nginx的数据结构集合(随时更新)

    在学习nginx的时候,因为其数据结构略多,看过后一般就忘记了.所以边学习边记录在这里吧,方便以后查看. ngx_buf_t:缓冲区结点 1: typedef struct ngx_buf_s ngx ...