在 Arthas 中调用 Spring Bean 方法

获取 Spring 应用上下文

使用工具类

如果你的项目中有一个工具类实现了 ApplicationContextAware 接口,如 cn.shutdown.pf.utils.SpringContextUtils,可以使用该类获取 ApplicationContext

@Component
public final class SpringContextUtils implements ApplicationContextAware {
   
   
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
   
   
        SpringContextUtils.applicationCo
<think>我们使用Arthas来获取正在运行的Spring应用的所有路由和过滤器信息。Arthas是一款Java诊断工具,通过其命令可以动态查看JVM状态、调用方法等。对于Spring应用,我们可以利用Arthas调用Spring内部的方法来获取路由和过滤器信息。 ### 获取路由信息 Spring MVC中,路由信息通常存储在`RequestMappingHandlerMapping`类的`mappingRegistry`属性中。我们可以通过Arthas的`ognl`命令来获取。 #### 步骤: 1. **找到目标类的ClassLoader**:由于Spring应用通常使用多个ClassLoader,我们需要先确定目标类的ClassLoader。 2. **使用ognl表达式获取路由信息**:通过访问`RequestMappingHandlerMapping`实例的`mappingRegistry`属性。 ### 获取过滤器信息 过滤器信息可以从`FilterRegistrationBean`或直接通过Servlet容器的`FilterChain`获取。在Spring Boot中,我们可以通过`ApplicationContext`获取所有的`FilterRegistrationBean`。 #### 步骤: 1. **获取Spring的ApplicationContext**:通过Arthas获取Spring的ApplicationContext实例。 2. **从ApplicationContext中获取所有FilterRegistrationBean**:然后遍历这些bean获取过滤器信息。 ### 具体操作命令: #### 1. 启动Arthas并连接到目标应用 ```bash java -jar arthas-boot.jar ``` #### 2. 获取Spring的ApplicationContext 首先,我们需要找到Spring的ApplicationContext。通常可以通过WebApplicationContextUtils类或从ServletContext中获取,但更简单的方式是查找已经加载的ApplicationContext实例。 ```bash # 查找所有ApplicationContext实例 sc -d org.springframework.context.ApplicationContext ``` 假设得到的类加载器hash是`1234abcd`,然后使用: ```bash # 获取ApplicationContext ognl -c 1234abcd '#context=@org.springframework.web.context.ContextLoader@getCurrentWebApplicationContext(), #context.getBean("requestMappingHandlerMapping").getHandlerMethods().keySet().stream().map(k->k.getPatternsCondition().getPatterns()).collect(@java.util.stream.Collectors@toSet())' ``` 但是上述命令可能较复杂,我们可以分步骤获取。 #### 3. 获取所有路由的URI 更直接的方式是获取`RequestMappingHandlerMapping`的实例,然后调用其`getHandlerMethods()`方法,然后提取路径。 ```bash # 找到RequestMappingHandlerMapping类的加载器 sc -d org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping # 假设类加载器hash为5678efab # 获取RequestMappingHandlerMapping实例 ognl -c 5678efab '@org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping@getHandlerMethods().keySet().{ #this.getPatternsCondition().getPatterns() }' ``` #### 4. 获取所有过滤器信息 首先获取ApplicationContext,然后获取所有类型为FilterRegistrationBeanbean。 ```bash # 获取ApplicationContext ognl -c 1234abcd '#context=@org.springframework.web.context.ContextLoader@getCurrentWebApplicationContext(), #filterBeans=#context.getBeansOfType(@org.springframework.boot.web.servlet.FilterRegistrationBean@), #filterBeans.values().{ #this.getFilter().getClass().getName() + ": " + #this.getUrlPatterns() }' ``` ### 注意事项 1. **Spring Boot版本差异**:不同版本的Spring Boot中,获取路由和过滤器的方式可能略有不同。 2. **Arthas版本**:确保使用较新版本的Arthas(如3.5.0以上)。 3. **安全权限**:目标应用需要允许Arthas访问,且运行Arthas的用户需要有足够的权限。 ### 替代方案:使用Arthas的dashboard命令 Arthas的`dashboard`命令可以查看所有Web请求的路径,但无法列出所有路由和过滤器。因此,上述方法更直接。 §§相关问题§§ 1. Arthas中如何动态监控Spring应用的请求处理过程? 2. 除了ognl命令,还有哪些Arthas命令可以用于诊断Spring应用? 3. 如何通过Arthas获取Spring应用中的Bean列表及其属性? 4. 在Spring Boot 2.x和3.x中获取路由信息的方法有何不同? 5. 使用Arthas获取路由信息时遇到类加载器隔离问题如何解决?</think>### 使用 Arthas 获取 Spring 应用的路由和过滤器信息 Arthas 是阿里开源的 Java 诊断工具,无需重启应用即可实时获取 Spring 应用的路由和过滤器信息。以下是完整操作指南: #### 1. **获取所有路由信息** ```bash # 启动 Arthas 附加到目标应用 ./arthas-boot.jar --select <pid> # 获取 Spring MVC 路由映射 [arthas@12345]$ ognl '@org.springframework.web.context.support.WebApplicationContextUtils@getWebApplicationContext(context).getBean("requestMappingHandlerMapping").getHandlerMethods().keySet().{ #this.getPatternsCondition().getPatterns() }' # 输出示例 @HashSet[ @String[/api/users], @String[/api/products/{id}], @String[/health] ] ``` #### 2. **获取过滤器信息** ```bash # 获取所有注册的过滤器 [arthas@12345]$ ognl '@org.springframework.web.context.support.WebApplicationContextUtils@getWebApplicationContext(context).getBeansOfType(javax.servlet.Filter).keySet()' # 查看特定过滤器配置 [arthas@12345]$ ognl '@org.springframework.web.context.support.WebApplicationContextUtils@getWebApplicationContext(context).getBean("characterEncodingFilter").{ #this.getInitParameters() }' ``` #### 3. **Spring Cloud Gateway 路由获取** ```bash # 获取 Gateway 路由定义 [arthas@12345]$ ognl '@org.springframework.web.context.support.WebApplicationContextUtils@getWebApplicationContext(context).getBean("cachedRouteLocator").getRoutes().{ #this.getId() + " -> " + #this.getUri() }' # 获取全局过滤器 [arthas@12345]$ ognl '@org.springframework.web.context.support.WebApplicationContextUtils@getWebApplicationContext(context).getBeansOfType(org.springframework.cloud.gateway.filter.GlobalFilter).keySet()' ``` #### 4. **高级诊断命令** ```bash # 监控路由调用情况 [arthas@12345]$ monitor -c 5 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter handleInternal # 查看过滤器执行链 [arthas@12345]$ stack org.apache.catalina.core.ApplicationFilterChain doFilter ``` #### 5. **结果导出与可视化** ```bash # 将路由信息导出到文件 [arthas@12345]$ ognl -o json --writeFile routes.json '@org.springframework.web.context...getPatterns()' # 启动 HTTP 诊断服务 [arthas@12345]$ profiler start -d 30 --format json ``` ### 实用技巧 1. **模糊搜索路由**:使用 `sc -d *HandlerMapping` 查找路由处理类 2. **实时调试**:`trace` 命令监控特定路由的执行耗时 3. **过滤器排序**:`watch` 命令查看 `FilterRegistrationBean` 的 order 值 4. **动态更新**:`redefine` 命令热更路由配置类 5. **安全过滤**:结合 `tt` 命令分析 Spring Security 的过滤器链 ### 注意事项 1. 需要目标应用开启 Servlet 3.0+ 支持 2. Spring Boot 2.x/3.x 的 Bean 名称可能不同 3. 对云原生环境(K8s)需配置正确的端口转发 4. 生产环境建议通过 `--telnet-port` 指定安全端口 5. 使用完成后执行 `stop` 退出避免资源占用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值