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
。这种情况和上面的示例类似。
要么是不知道参数列表,而是通过反射 add
的 Method
对象去调用,这时候通过 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