背景:产品同类的订单会有不同的细节操作(增、改等),但是主流程确是一样的(校验、返回结果等);不同类产品采用类似动态代理的模式,利用反射机制,找到对应的逻辑实体执行对应的方法。现在处理的是细化到业务实体的公共主流程中不同操作的不同方法
clazz= PolicyConst.get(requestType);
if(clazz == null) return null;
return ApplicationContextUtil.getContext().getBean(clazz);//spring获取实例,一般情况采用是clazz.newInstance()
标准入口就不详述了。
自定义注解:
@Retention(RUNTIME)
@Target({FIELD, METHOD})
public @interface RequestType {
String value() default "";
}
这里实现的作用是通过requestType类型来控制执行的方法;
调用方式:
//继承抽象类的方式
super.findMethod(this, head.getRequestType(), EXECUTE).invoke(this, jsonRequest);
方法定义:(通过特殊字符+request类型==>确定调用的方法)
@RequestType(EXECUTE+PolicyConst.RequestType)
public QueryResultObject executeFun_001(JsonRequest jsonRequest) {}
核心方法:
public static Method findMethod(Object bean, String requestType, String method_suffix) {
Method method = null;
RequestType rt = null;
for(Method m: bean.getClass().getDeclaredMethods()){
rt = m.getAnnotation(RequestType.class);
if (Beans.isNotEmpty(rt) && rt.value().equals(method_suffix+requestType)) {
method = m;
break;
}
}
if(Beans.isEmpty(method)){
throw new e;
}
return method;
}
附带一个常规反射的性能测试(比较粗糙),大致可以看出好用的东西一般风险性都比较高:
public class MainReflect {
public static void main(String[] args) {
Runtime r = Runtime.getRuntime();
Apple apple1 = new Apple("red", 500);
StopWatch sw = new StopWatch();
sw.start();
r.gc();//计算内存前先垃圾回收一次
long startMem = r.freeMemory(); // 开始Memory
for (int i = 0; i < 100; i++) {
//无论是使用泛型,还是常规的classforname
reflect(apple1);
}
long endMem =r.freeMemory(); // 末尾Memory
sw.stop();
System.out.println("测试耗时1:"+sw.getTotalTimeMillis());
System.out.println("测试耗内存1:"+ (startMem-endMem));
StopWatch sw2 = new StopWatch();
sw2.start();
r.gc();//计算内存前先垃圾回收一次
long startMem2 = r.freeMemory(); // 开始Memory
for (int i = 0; i < 100; i++) {
apple1.getColor();
}
long endMem2 =r.freeMemory(); // 末尾Memory
sw2.stop();
System.out.println("测试耗时2:"+sw2.getTotalTimeMillis());
System.out.println("测试耗内存2:"+ (startMem2-endMem2));
}
private static <T> void reflect(T t) {
try {
t.getClass().getMethod("getColor").invoke(t).toString();
} catch (Exception e){
e.printStackTrace();
}
}
}
public class Apple {
private String color;
private int weight;
public Apple(String color, int weight) {
this.color = color;
this.weight = weight;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
}