学习arthas(八)查找某个被加载的类
Arthasadmin 发布于:2023-09-30 14:41:52
阅读:loading
有些时候查找某个被加载的类也是有必要的,当然抛出ClassNotFound异常的除外,特别是针对于需要改写一些第三方框架组件的源代码时,也许是因为源码中的实现不够理想,要么是需要做一些个性化的事情,通常我们的做法并不是去改写这些三方库的源代码jar,而是拷贝一份源代码放置于项目中的同包名同类名,再调整启动脚本优先加载项目内的classes或jar,而后再加载这些第三方的jar,使得预先加载的是项目中的代码(项目中修改过的代码)。所以,基本上有这几种场景是这么干过:
(1)在使用Google的zxing生成二维码组件时,由于它默认生成的二维码带有一些宽度的白色边框(差不多10像素),如果需要取消白边,通常的做法就是改动源代码(本站有对于此问题的解决);
(2)在使用第三方登录时(如:QQ、微博等)它们提供的SDK示例程序的参数都使用配置文件存储的,本站在实现时将这些配置文件存储于数据库中,所以也通过改项目类加载的形式解决;
(3)本站在使用Spring Session做的session管理,但是又不明确它的过滤器拦截的URL范围是什么样子的,所以也可以通过改写它的过滤器的方式增加一些日志输出,用于分析它的URL拦截范围;
(4)工作中也有在升级JPA后使用它的命名方法报错的场景,领导在对于源码分析调试后发现高版本的JPA对于命名方法的属性解析实现做了更改,以至于前期所写的巨多老代码失效了,也通过这种方式改写的源代码进行覆盖解决;
所以,本次实践的目的是使用arthas来分析项目中的两个同包同名的类具体来自于哪个jar包当中的实现,以Spring Session中的过滤器代码覆盖为例,我需要覆盖spring session中的过滤器,因为它默认将拦截全部的路径,导致一个页面中引入的JS、CSS、IMAGE、FONT等各个资源都被拦截,导致页面响应超慢,所以我需要覆盖实现它,详细如下文所示。
package org.springframework.boot.autoconfigure.session;
import ...;
/**
* Configuration for customizing the registration of the {@link SessionRepositoryFilter}.
*
* @author Andy Wilkinson
*/
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(SessionRepositoryFilter.class)
@EnableConfigurationProperties(SessionProperties.class)
@Slf4j
public class SessionRepositoryFilterConfiguration {
@Bean
FilterRegistrationBean<SessionRepositoryFilter<?>> sessionRepositoryFilterRegistration(
SessionProperties sessionProperties, SessionRepositoryFilter<?> filter) {
log.warn("注意:已使用SessionRepositoryFilterConfiguration重载实现");
//定义session 拦截路径范围
FilterRegistrationBean<SessionRepositoryFilter<?>> registration = new FilterRegistrationBean<>(filter);
registration.addUrlPatterns("*.html" , "*.zip" , "*.exe" , "/system/login" , "/" , "/index.html" ,
"/third-login/loginCallback" , "/third-login/baiduCallback" , "/tencent-login/tencentCallback" ,
"/swagger-resources" , "/swagger-resources/**");
registration.addInitParameter("excludeUrls", "/statics/**");
registration.setDispatcherTypes(getDispatcherTypes(sessionProperties));
registration.setOrder(sessionProperties.getServlet().getFilterOrder());
return registration;
}
private EnumSet<DispatcherType> getDispatcherTypes(SessionProperties sessionProperties) {
SessionProperties.Servlet servletProperties = sessionProperties.getServlet();
if (servletProperties.getFilterDispatcherTypes() == null) {
return null;
}
return servletProperties.getFilterDispatcherTypes().stream().map((type) -> DispatcherType.valueOf(type.name()))
.collect(Collectors.collectingAndThen(Collectors.toSet(), EnumSet::copyOf));
}
}
(启动脚本)
启动脚本共引入了三个文件夹中的jar,分别是如下场景,按优先指定的顺序,可以起到优先加载的目的,所以若“org.springframework.boot.autoconfigure.session.SessionRepositoryFilterConfiguration”类在lib-local范围被定义,同时也在lib-jar中被定义,那么最终生效的则是lib-local中的class,除了可以使用Log输出日志来证明外,现在使用arthas来展示结果,所以参考如下图所示:
(验证结果一)
(验证结果二)
使用arthas里的jad也可以查看已加载的类的所在位置和反编译后的源码,如下图所示:
点赞
发表评论
评论列表
留言区
- 开篇学习arthas啦
- 学习arthas(一)安装与入门介绍
- 学习arthas(二)Web Console控制台
- 学习arthas(三)命令大全与简单命令
- 学习arthas(四)系统命令
- 学习arthas(五)类命令
- 学习arthas(六)增强命令
- 学习arthas(七)arthas-tunnel-server的摸索
- 学习arthas(九)动态执行一些代码
- 学习arthas(十)方法执行结果监控
- 学习arthas(十一)输出方法调用栈
- 学习arthas(十二)跟踪方法代码的执行
- 学习arthas(十三)监视代码的执行结果
- 学习arthas(十四)方法执行时的时空隧道
- 学习arthas(十五)无侵入的热部署
- 学习arthas(十六)热点功能火焰图