4
回答
如何在运行时获取 Java 方法定义的顺序
利用AWS快速构建适用于生产的无服务器应用程序,免费试用12个月>>>   
先贴代码:

Handler.java
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Handler {
	String name();
	int order();
}

Controller.java

public class Controller {

	@Handler(name = "创建", order = 1)
	public void create() {
	}

	@Handler(name = "更新", order = 2)
	public void update() {
	}

	@Handler(name = "删除", order = 3)
	public void delete() {
	}

}

InitHandler.java 

public class InitHandler {

	public static void main(String[] args) {

		// 遍历方法
		for (Method method : Controller.class.getMethods()) {
			Handler handler = method.getAnnotation(Handler.class);

			// 过滤掉没有 Handler 注解的
			if (handler == null) {
				continue;
			}

			// 提取名字和序号
			String handlerName = handler.name();
			int showOrder = handler.order();

			// 持久化
			saveHandler(method.getName(), handlerName, showOrder);
		}
	}

	public static void saveHandler(String methodName, String handlerName, int showOrder) {
		// 保存到数据库对应的表:handler_tb(method_name, handler_name, show_order)
		System.out.println(methodName + "," + handlerName + "," + showOrder);
	}

}

我正在设计的功能是:
利用注解和反射将 MVC 中的 Controller 处理方法持久化到数据库中,用于权限分配和计算。 

以上是一个精简版的例子,例子中的 order 是通过@Handler配置的,
这样导致在编写 Controller 时还要去设置这个序号,比较麻烦。

想要把这个 order 配置项去掉,直接获取方法在类中定义的行号,用行号作为 order 的值。

不知道有什么办法可以实现,有没有相关的类库可以帮助实现


举报
JeffreyLin
发帖于3年前 4回/905阅
共有4个答案 最后回答: 3年前
自己用 javassist 解决了,分享给大家。

InitHandler.java 更改为:
public class InitHandler {

	public static void main(String[] args) {
		try {
			parseHandler(Controller.class);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void parseHandler(Class<?> clazz) throws NotFoundException, ClassNotFoundException {
		ClassPool pool = ClassPool.getDefault();
		String className = clazz.getName();
		CtClass cc = pool.get(className);
		for (CtMethod cm : cc.getMethods()) {
			Handler handler = (Handler) cm.getAnnotation(Handler.class);
			if (handler != null) {
				String methodName = cm.getLongName();
				String handlerName = handler.name();
				int startLine = cm.getMethodInfo().getLineNumber(0);
				saveHandler(className, methodName, handlerName, startLine);
			}
		}
	}

	public static void saveHandler(String className, String methodName, String handlerName, int startLine) {
		System.out.println(className + "." + methodName);
		System.out.println("handlerName=" + handlerName);
		System.out.println("startLine=" + startLine);
		System.out.println();
	}

}




反射可以获取行号?  这个应该无法实现,如果要获取行号应该是需要通过读文件的方式去获取吧
--- 共有 1 条评论 ---
JeffreyLin是的,貌似 javassist 可以,正在研究…… 3年前 回复
得到行号的意义是什么?
--- 共有 3 条评论 ---
JeffreyLin回复 @小翔 : 是的,这个排序对系统维护人员来说很重要,虽然之前用 @Handler(name = "创建", order = 1) 可以解决,但是对开发人员有点麻烦,现在使用代码行号排序就可以把 order = 1 这个配置去掉,开发时增/减 controller 方法也不用手动去调整 order 的值了 3年前 回复
小翔回复 @JeffreyLin : 哦,你这个是约定排在前面的权限小是吧。只是想要个排序。 3年前 回复
JeffreyLin比如说 search, save, delete 这三个方法,可能普通认证用户有 search 权限,普通管理员有 save 权限,超级管理员有 delete 权限,那么在编写 Controller 的时候,只要把 search 方法写在前面,把 delete 方法写在后面,这样在授权页面显示权限的时候就可以按行号排序,级别低的权限排在前面,提高授权效率。 3年前 回复
顶部