最近公司一个项目(T)需要整合另外 2 个项目(A、B)的集成,于是,我们的方案是打包A、B成 jar,然后 deploy 到中央仓库,再用 T 去拉 maven pom,但是发现一个问题,debug T 项目的时候里面都是 class 文件(正常),大家都知道,调试 class 文件反编译的结果和原生 java 代码可能是有出入的,举个例子……
Java 文件
publicRequestInterceptorrequestInterceptor() { returntemplate-> { // 从父线程中获取 request,避免子线程开启时候丢失了父 requestif (Objects.isNull(RequestContextHolder.getRequestAttributes()) ||RequestContextHolder.getRequestAttributes() instanceofNonWebRequestAttributes) { RequestContextHolder.setRequestAttributes(nonWebRequestAttributes, Boolean.TRUE); HttpServletRequestrequest=this.getHttpServletRequestSafely(); if (null!=request&&null!=request.getAttribute("X-Request-No")) { template.header("X-Request-No", request.getAttribute("X-Request-No").toString()); } RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true); template.header("x-tenant-id", nonWebRequestAttributes.getTenantId()); } else { RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true); ServletRequestAttributesattributes= (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes(); if (null!=attributes) { HttpServletRequestrequest=attributes.getRequest(); Enumeration<String>headerNames=request.getHeaderNames(); if (headerNames!=null) { while (headerNames.hasMoreElements()) { Stringname=headerNames.nextElement(); Stringvalue=request.getHeader(name); // 一定要去掉 content-length 否则跟自己feign调用时传参字符数会对不上而报错if (name.equalsIgnoreCase("x-tenant-id")) { template.header(name, value); } } } } } }; }
Class 文件
publicRequestInterceptorrequestInterceptor() { return (template) -> { if (!Objects.isNull(RequestContextHolder.getRequestAttributes()) &&!(RequestContextHolder.getRequestAttributes() instanceofNonWebRequestAttributes)) { RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true); ServletRequestAttributesattributes= (ServletRequestAttributes)RequestContextHolder.currentRequestAttributes(); if (null!=attributes) { HttpServletRequestrequestx=attributes.getRequest(); Enumeration<String>headerNames=requestx.getHeaderNames(); if (headerNames!=null) { while(headerNames.hasMoreElements()) { Stringname= (String)headerNames.nextElement(); Stringvalue=requestx.getHeader(name); if (name.equalsIgnoreCase("x-tenant-id")) { template.header(name, newString[]{value}); } } } } } else { RequestContextHolder.setRequestAttributes(this.nonWebRequestAttributes, Boolean.TRUE); HttpServletRequestrequest=this.getHttpServletRequestSafely(); if (null!=request&&null!=request.getAttribute("X-Request-No")) { template.header("X-Request-No", newString[]{request.getAttribute("X-Request-No").toString()}); } RequestContextHolder.setRequestAttributes(RequestContextHolder.getRequestAttributes(), true); template.header("x-tenant-id", newString[]{this.nonWebRequestAttributes.getTenantId()}); } }; }
发现问题
- 发现了吗,在第一个 if 语句里是不一样的,这也还好,关键是有时候 debug 逻辑是错乱的,比如我遇到过一次调试这个 class 文件,从 else 的逻辑走完,居然跑到了第一个 if 语句里面的第三行逻辑,简直一脸懵的状态~但是当时 deploy 上去也没所谓的 java 源码,那怎么办呢?
解决方案
其实发现可以手动的去关联 java 代码,当然这个需要自己保证代码是一致性的,如图所示
点击箭头的地方,弹出一个窗口,进行代码关联,当然这里有一个小技巧,不需要精准定位到具体哪个 java 文件,只要选择在其范围的包,IDEA会自动搜索该对应的文件,还是很方便的噢~
提示找到该文件,点击 OK 即可!
看,大功告成,已经是 java 文件,当然右上角还有一个 Show diff 的功能,可以对比不同地方,当然如果 java 文件和 class 文件因为上文提到过本身代码就是不同,所以肯定会有差异,目前还没那么智能到反编译与原生 java 代码的转换差异,所以这个还是需要自己手动比较下,是否 2 个文件匹配!