程序员就是不断的踩坑脱坑,人生又何尝不是这样呢?
这段代码的初衷是想通过一个入口传入的类型不同通过反射去调用可能位于不同service下的不同方法,当然可能返回值也不同。
@Service
@Slf4j
public class WorkOrderDispatchService {
@Resource
private Reflections reflections;
public Object dispatch(Integer type,String cowShed){
try{
//扫描service下所有被@WorkOrderDispatch注解的方法
Set<Method> methods = reflections.getMethodsAnnotatedWith(WorkOrderDispatch.class);
//定位方法上@WorkOrderDispatch的type字段int[]包含传入的type的方法
Method method = methods.stream().filter(m -> Lists.newArrayList(m.getAnnotation(WorkOrderDispatch.class).type()).contains(type) ).findFirst().get();
//获取将被调用的方法的Class对象
Class clazz = method.getDeclaringClass();
//通过Class找到对应的service
Object service = ApplicationContextUtil.getBean(clazz);
Object result = method.invoke(service,type,cowShed);
return result;
}catch (Exception e){
log.error("派单出错...",e);
return null;
}
}
}
@Retention(RetentionPolicy.RUNTIME)
@Target(value = ElementType.METHOD)
@Documented
public @interface WorkOrderDispatch {
int[] type();
}
@WorkOrderDispatch(type = {2,8})
public void test(Integer type,String cowShed){
System.out.println("测试方法");
}
以前使用Lists.newArrayList()别的不是基础类型的时候,比如:
Student[] students的一个数组使用该方法得到的是一个List<Student>的对象,这次因为使用注解,而注解里的元素不允许是Integer[]数组。导致传入一个int[]数组调用List.newArrayList(int[])得到的是List<int[]>这样的类型,所以匹配不到,调用不了我的test方法。debug了一下,自动转换成了二维数组,int[]被看成是一个E的对象了。

图1
如果可变参数定义成基本类型,也是可以的

图2
最后改成Integer[]类型的数组解决问题
public Object dispatch(Integer type, String cowShed) {
try {
//扫描service下所有被@WorkOrderDispatch注解的方法
Set<Method> methods = reflections.getMethodsAnnotatedWith(WorkOrderDispatch.class);
//获取WorkOrderDispatch注解包含该type的方法,不要多个方法有同一个type
Method method = methods.stream().filter(m -> Lists.newArrayList(Arrays.stream(m.getAnnotation(WorkOrderDispatch.class).type())
.boxed().toArray(Integer[]::new)).contains(type)).findFirst().get();
//获取将被调用的方法的Class对象
Class clazz = method.getDeclaringClass();
//通过Class找到对应的service
Object service = ApplicationContextUtil.getBean(clazz);
//反射调用该方法
Object result = method.invoke(service, type, cowShed);
return result;
} catch (Exception e) {
log.error("派单出错...", e);
return null;
}
}
这里总结一下注解元素允许的类型:
- 基本类型 byte short int long float double char boolean
- String
- Class
- Enum
- Annotation
- 上面所有类型的数组