在使用ReflectionUtils反射处理调用方法的时候报错了
错误:
java.lang.NullPointerException: null
at org.springframework.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:282) ~[spring-core-5.1.9.RELEASE.jar!/:5.1.9.RELEASE]
原因: 未找到对应的方法。
处理思路:
先单元测试,看看该方法是否可以正常调用。 如果可以正常调用,说明传递的参数有问题。
先学习下ReflectionUtils看下寻找方法和调用方法的参数
ReflectionUtils
findMethod
ReflectionUtils.findMethod
@Nullable
public static Method findMethod(Class<?> clazz, String name) {
return findMethod(clazz, name);
}
@Nullable
public static Method findMethod(Class<?> clazz, String name, @Nullable Class... paramTypes) {
}
name 是对应方法名 paramTypes 对应参数的类型,比如String.class
invokeMethod
@Nullable
public static Object invokeMethod(Method method, @Nullable Object target) {
return invokeMethod(method, target);
}
@Nullable
public static Object invokeMethod(Method method, @Nullable Object target, @Nullable Object... args) {
try {
return method.invoke(target, args);
} catch (Exception var4) {
handleReflectionException(var4);
throw new IllegalStateException("Should never get here");
}
}
args 是参数, Target 指什么呢?
应该是一个类
SpringUtils
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringUtils.applicationContext = applicationContext;
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
public static <T> T getBean(Class<T> clazz) {
return applicationContext.getBean(clazz);
}
}
Service
@Service
public class AopService {
public void getAlarmInfo(){
System.out.println("test ReflectionUtils no params");
}
public void getAlarmInfo(String alarmLevel){
System.out.println("test ReflectionUtils has params alarmLevel "+alarmLevel);
}
}
无参数调用
@Test
public void testNoParam() {
// 请求的参数类型得保持一致 name 对应方法名
Method mh = ReflectionUtils.findMethod(AopService.class, "getAlarmInfo");
System.out.println(mh);
assert mh != null;
ReflectionUtils.invokeMethod(mh, SpringUtils.getBean("aopService"));
}
有参数调用
@Test
public void testWithParam() {
// 请求的参数类型得保持一致 name 对应方法名
String alaramLevel = "3";
// 参数设置
List<String> params = new ArrayList<>();
params.add(alaramLevel);
// 参数处理
Class[] partypes = new Class[0];
Object[] arglist = new Object[0];
if (params.size() > 0) {
int paramCnt = params.size();
partypes = new Class[paramCnt];
arglist = new Object[paramCnt];
for (int i = 0; i < paramCnt; i++) {
partypes[i] = String.class;
arglist[i] = params.get(i);
}
}
// 请求的参数类型得保持一致 name 对应方法名
Method mh = ReflectionUtils.findMethod(AopService.class, "getAlarmInfo", partypes);
System.out.println(mh);
assert mh != null;
ReflectionUtils.invokeMethod(mh, SpringUtils.getBean("aopService"), arglist);
}
总结:
使用ReflectionUtils反射的时候,如果报错,先确认该方法的参数是不是都是字符类型,参数个数是否对应;然后再用上面的方法调用是否正常,最后确认传的实际参数是什么? 如果单元测试是正常的,就是传的参数有问题。