java 断点跳到注释,给注解打断点的一种方法
Controllor中有如下的方法,
@HttpFeatures(contentType="application/json")
@Get("send/{appId:[0-9]+}")
@Post("send/{appId:[0-9]+}")
public String sendMail(@Param("data") String dataBase64,@Param("appId") long appId) {
//...
}
想知道这几个注解何时被谁于何处给调用. 又不能在注解所在行直接加断点. 只好退而求其次在Method(java.lang.reflect.Method)的注解相关方法中打断点
T java.lang.reflect.Method.getAnnotation(Class annotationClass)
Annotation[] java.lang.reflect.Method.getDeclaredAnnotations()
Annotation[][] java.lang.reflect.Method.getParameterAnnotations()
但是在断点处,看不到变量的实际值.如下所示:
于是在本地覆盖java.lang.reflect.Method(即在当前工程中创建一个包为java.lang.reflect,在该包下创建一个名为Method的类,内容和jdk源码一样.)并在相关处添加断点. 但压根就不进来,还是找jdk中的Method.看来没办法覆盖java核心类库(如rt.jar)中的类了(因为它们在程序启动时是被顶层(或根)类加载器所加载,一旦完成加载,就不会重复加载(同名类)了.).
那么假如将rt.jar中的Method.class给删除了呢,再在本地覆盖Method,不就可以加载本地的Method了吗. 但证实不可行,因为立即就报错了:
Error occurred during initialization of VM
java/lang/NoClassDefFoundError: java/lang/reflect/Method
显然Method被其他核心类所引用.
只好自己编译一个jdk了(且是debug版的jdk,否则调试时还是看不到变量值). 幸好Ubuntu中编译jdk还是挺顺利的.
于是修改项目的JRE为新编译的支持debug的jdk.如下所示:
这时可以清晰的看到变量值了.如下所示:
但是有太多注解了,而只想看到net.paoding.rose.web.annotation包下的那些注解.如net.paoding.rose.web.annotation.HttpFeatures.
于是修改Method的方法(当然需要重新编译了),如
public T getAnnotation(Class annotationClass){
//添加了如下的代码
if(annotationClass.getName().startsWith("net.paoding.rose.web.annotation"))
System.out.println(annotationClass.getName());
//......
}
将断点放在if方法内部, 这样进入断点的注解就是想要探究的注解了.
其他几个方法做同样的处理.
虽然还是有一些干扰项,如net.paoding.rose.web.annotation.Ignored.但还是可以接受的.
很快就知道HttpFeatures注解是被谁在何处给调用的了.
上图左侧显示,是在ActionEngin的构造方法中98行被调用.该行代码如下所示:
HttpFeatures httpFeatures = method.getAnnotation(HttpFeatures.class);
接下来看Get和Post在何处被调用. 这次是调用的Method另一个方法:
public Annotation[] getDeclaredAnnotations(){
//对源代码做了如下的修改:
//return AnnotationParser.toArray(declaredAnnotations()); //原代码
Annotation[] annotations = AnnotationParser.toArray(declaredAnnotations());
for(Annotation anno : annotations)
if(anno.toString().indexOf("net.paoding.rose.web.annotation")!=-1)
System.out.println(anno.toString());
return annotations;
}
这时在debug视图中的看到的内容为:
由左侧可知,是被ControllerRef在collectsShotcutMappings方法中所调用. 其相关代码为:
Annotation[] annotations = method.getAnnotations();
for (Annotation annotation : annotations) {
if (annotation instanceof Delete) {
restMethods.put(ReqMethod.DELETE, ((Delete) annotation).value());
} else if (annotation instanceof Get) {
restMethods.put(ReqMethod.GET, ((Get) annotation).value());
...
接下来看方法参数中的注解(如@Param("data") String dataBase64)何时何处被调用,显然应该在getParameterAnnotations方法中打断点.
同样在getParameterAnnotations添加了如下的代码:
for(int i=0; i
for(int j=0; j
if(result[i][j].toString().indexOf("net.paoding.rose.web.annotation")!=-1)
System.out.println(result[i][j].toString());
}
}
这时debug视图中的内容为:
由左侧可知,是在ParameterNameDiscovererImpl.getParameterNames处调用的,相关代码为:
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
String[] names = new String[parameterTypes.length];
Map counts = new HashMap();
for (int i = 0; i
Annotation[] annotations = parameterAnnotations[i];
for (Annotation annotation : annotations) {
String name = null;
if (annotation instanceof Param) {
name = ((Param) annotation).value();
......
同理可以修改Class类,在注解相关方法中添加一些代码,断点打在相应位置,可以得到类注解(如@Path("/mail"))的调用信息.
注:
若有Rose的源代码的话,导入到Eclipse中,直接在java类中搜索Get, Post, HttpFeatures即可.
补充:
Ubuntu环境编译OPENJDK(摘自周志明深入理解JAVA虚拟机)
安装依赖包
sudo apt-get install build-essential gawk m4 openjdk-6-jdk libasound2-dev libcups2-dev libxrender-dev xorg-dev xutils-dev x11proto-print-dev binutils libmotif3 libmotif-dev ant
在解压后的openjdk目录下创建如下的脚本,内容为:
export LANG=C
#启动JDK 需修改为当前系统已安装的jdk目录 毕竟jdk中的大部分类还是java写的,编译还得依赖已有的环境
export ALT_BOOTDIR=${JAVA_HOME}
export ALLOW_DOWNLOADS=true
#并行编译的线程数,设置为和CPU内核数量一致即可
export HOTSPOT_BUILD_JOBS=4
export ALT_PARALLEL_COMPILE_JOBS=4
export SKIP_COMPARE_IMAGES=true
export USE_PRECOMPILED_HEADER=true
export SKIP_FASTDEBUG_BUILD=false
export DEBUG_NAME=fastdebug
BUILD_DEPLOY=false
BUILD_INSTALL=false
#编译后的JDK输出目录 ${openjdk_install_path}为当前openjdk目录
export ALT_OUTPUTDIR=${openjdk_install_path}/build
unset JAVA_HOME
unset CLASSPATH
make 2>&1 | tee $ALT_OUTPUTDIR/build.log
注: 标红部分表示需修改为自己环境的路径.
执行该脚本,若一切顺利的话,在${openjdk_install_path}下会看到一个目录(build-fastdebug),进入该目录,会有一个j2sdk-image的目录,该目录便是编译好的jdk对应的目录. 若修改了源码(源码的路径为:${openjdk_install_path}/jdk/src/share/classes)的话, 当然需要重新编译(即再次执行上述脚本).
java 断点跳到注释,给注解打断点的一种方法相关推荐
- Spring注解定义 bean 的12种方法
前言 在庞大的java体系中,spring有着举足轻重的地位,它给每位开发者带来了极大的便利和惊喜.我们都知道spring是创建和管理bean的工厂,它提供了多种定义bean的方式,能够满足我们日常工 ...
- 【错误记录】NDK 导入外部 so 动态库报错 ( java.lang.UnsatisfiedLinkError | Android Studio 配置外部 so 动态库两种方法 )
文章目录 一.报错信息 二.解决方案 ( Android Studio 配置外部 so 动态库两种方法 ) 1.jniLibs 目录存放 2.libs 目录存放 一.报错信息 外部引用 so 动态库 ...
- java怎么判断字符是否为空?有哪几种方法?
关于java判断字符是否为空的文章早已是非常多了,本文是对我个人过往学习java,理解及应用java的一个总结.此文内容涉及java判断字符是否为空的四种方法,以及相关问题补充,希望对大家有所帮助. ...
- java 遍历删除list_Java list利用遍历进行删除操作3种方法解析
这篇文章主要介绍了Java list利用遍历进行删除操作3种方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Java三种遍历如何进行list ...
- java字符串转数字,各种数字转字符串的3种方法
java字符串转数字的方法 1.转化为int型数字 Integer.parseInt(String s) Integer.valueOf(String s); 2. ...
- java 把map转换成json_map转换成JSON的3种方法
1 json-lib net.sf.json-lib json-lib 2.4 jdk15 import java.util.HashMap; import java.util.Map; import ...
- Java中让浮点型数据保留两位小数的四种方法
hello,你好呀,我是灰小猿,一个超会写bug的程序猿! 今天在进行开发的过程中遇到了一个小问题,是关于如何将double类型的数据保留两位小数.突然发现这方面有一点欠缺,就来总结一下. 一.Str ...
- web java获取当前时间_Java 获取当前系统时间的三种方法
准备工作: import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; 方式一: /** ...
- java list转set去重_Java中List去重的四种方法
Java中List去重的四种方法 package com.lxz.test; import java.util.ArrayList; import java.util.HashSet; import ...
- java发送get请求_java发送http get请求的两种方法(总结)
长话短说,废话不说 一.第一种方式,通过HttpClient方式,代码如下: public static String httpGet(String url, String charset) thro ...
最新文章
- 深度学习训练,选择P100就对了
- PTA 1002 Business (35分)
- DockerCompose-初始Compose
- Python: 编程遇到的一些问题以及网上解决办法?
- WCF netTcpBinding寄宿到IIS7
- android开源2016_出版商的选择:2016年顶级开源书籍
- JavaScript Ajax与Comet——“其他跨域技术”的注意要点
- 蓝软服务器文件监控同步系统,蓝软7000ERP通用操作使用教程
- Bailian3179 最长单词【字符串】
- 相关滤波跟踪·MOSSE算法的梳理
- 麦咖啡MACfEE服务器安全防护设置技巧!
- 数据安全-整体解决方案
- 微信服务号使用微信支付
- arduino超声波测距接线图详细_Arduino学习笔记A2 - Arduino连接超声波传感器测距
- 计算机图形函数,计算机图形学常用函数.ppt
- 房屋租赁合同电子版(可下载)
- 微积分导论--Continuity
- Xbrowser无法连接到Linux的解决办法
- Spark 报错 Failed to delete: C:\Users\lvacz\AppData\Local\Temp\spark-*
- 工业互联网+化工园区一体化智慧管理解决方案