java反射获取方法时,设置方法的参数类型问题?

大家好,请看我的问题描述:

public class Test{

public void add(String name,String age) {

//这里需要通过判断Test类中是否有addAfter方法,如果有就执行addAfter(name,age)

}

public void addAfter(String name,String age) {

System.out.println("我执行啦!");

}

}

如上,当add方法被调用的时候,会去判断当前Test类中是否有addAfter方法(addAfter方法的参数与add的参数是一致的,后期这个判断会放到注解中通过切面来判断)

通过反射获取addAfter的时候需要指定参数类型:

Method methodAddAfter = testClass.getMethod("addAfter",String.class,String.class);

现在的问题是getMethod的后两个参数 String.class,String.class 是动态的(取决于add的参数类型),我想问的是:如何将add的参数类型作为参数传入到testClass.getMethod中去呢?谢谢!?


另外,我上面的目的其实就是想为add添加一个后置方法,类似thinkphp中的前置、后置方法:

namespace Home\Controller;

use Think\Controller;

class IndexController extends Controller{

//前置操作方法

public function _before_index(){

echo 'before<br/>';

}

public function index(){

echo 'index<br/>';

}

//后置操作方法

public function _after_index(){

echo 'after';

}

}

那么springboot中有没有什么好的解决方案呢(每个方法自动去匹配:_before_当前方法名、_after_当前方法名)?


回答:

ddAfter方法的参数与add的参数是一致的,既然你前面约定了这个约束,当你调用add方法的时候,aop一拦add方法,参数类型就都有了;



回答:

如果是直接在 add 里找 afterAdd 来调用,大概应该是这样:

public void add(String name, int age) {

out.printf("[add] %s (%d)%n", name, age);

// 下面是查找调用 afterAdd

var c = getClass();

try {

var m = c.getMethod("afterAdd", String.class, int.class);

m.invoke(this, name, age);

}

catch (Exception e) {

out.println(String.format("[Error] %s", e.getMessage()));

}

}

getMethod 的时候,知道方法名,也知道参数列表(就是当前 add() 的参数列表)。

如果采用 Annotation 来写,很大概率会有一个管理器,或者调用器。因为 Annotation 需要通过反射去获取。暂且给它命名为 Invoker。

那么 Invoker 在调用 add 的时候,要么是直接调用,这种情况下其参数列表是程序员知道的,所以可以传递这个参数列表去找 afterAdd。这种情况和上面的示例类似。

要么是不知道参数列表,而是通过反射 addMethod 对象去调用,这时候通过 Method.getParameterTypes() 是可以拿到参数列表的。

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface InvokeAfter {

String after();

}

Object invoke(T instance, Object... args) throws InvocationTargetException, IllegalAccessException {

// method 提前取了放在 field 里的

if (method == null || instance == null) { return null; }

var result = method.invoke(instance, args);

invokeAfter(instance, args);

return result;

}

void invokeAfter(T instance, Object... args) {

// 通过 method 反射对象去拿 Annotation

var a = method.getAnnotation(InvokeAfter.class);

if (a == null) { return; }

var c = instance.getClass();

try {

// 通过 method.getParameterTypes() 拿参数列表

var m = c.getMethod(a.after(), method.getParameterTypes());

m.invoke(instance, args);

}

catch (Exception e) {

out.println(e);

}

}

以上是 java反射获取方法时,设置方法的参数类型问题? 的全部内容, 来源链接: utcz.com/p/944997.html

回到顶部