我的目的是解耦合,需要缓存的加入缓存,统一管理。
反射会遇到一个坑,先上代码后填坑。
原先:
一个业务类:A
一个外部feign接口:D
调用流程图:
现在:
三个类:ABC
一个外部feign接口:D
调用流程图:
A业务类
public List<DTO> getInfo(Vo Vo) {
List<DTO> get = B.getFromRedisList(
RedisKeyConstant.Utils_get + Vo.toString(), "get", Vo, DTO.class);
return get;
}
B反射工具类
public static <T> List<T> getFromRedisList(String key, String me, Object param, Class<T> targetClass) {
GenericFastJsonRedisSerializer genericFastJsonRedisSerializer = new GenericFastJsonRedisSerializer();
if (redisTemplate.hasKey(key)) {
byte[] info = (byte[]) redisTemplate.execute((RedisCallback<byte[]>) connection -> connection.get(key.getBytes()));
if (info == null) {
return new ArrayList<>();
}
String deserialize = genericFastJsonRedisSerializer.deserialize(info).toString();
List<T> ts = JSON.parseArray(deserialize, targetClass);
return ts;
} else {
try {
Class<C> C = C.class;
Method[] methods = C.getMethods();
for (Method method : methods) {
if (method.getName().equals(me)) {
Object invoke = getValueObject(key, param, genericFastJsonRedisSerializer, method);
return (List<T>) invoke;
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
return new ArrayList<>();
}
private static Object getValueObject(String key, Object param, GenericFastJsonRedisSerializer genericFastJsonRedisSerializer, Method method1) {
Object invoke = new Object();
try {
invoke = method1.invoke(C, param);
final byte[] value = genericFastJsonRedisSerializer.serialize(invoke);
redisTemplate.execute((RedisCallback<Void>) connection -> {
connection.set(key.getBytes(), value);
connection.expire(key.getBytes(), PlanRedisKeyConstant.time_s);
return null;
});
return invoke;
} catch (IllegalAccessException e) {
log.error(e.getMessage(), e);
} catch (IllegalArgumentException e) {
log.error(e.getMessage(), e);
} catch (InvocationTargetException e) {
log.error(e.getMessage(), e);
} catch (SerializationException e) {
log.error(e.getMessage(), e);
}
return invoke;
}
C是Acl类
public VO get(List<String> List) {
return D.get(List);
}
D外部接口feign
@PostMapping({"get"})
List<DTO> get(@RequestBody Vo Vo);
注意点:
反射出来的类,里面通过@Autowired注入的类全部是空,如果直接使用
method.invoke(反射出来的类, param)
会报错。
应该改为:
先把需要反射的类注入进来,然后调用反射的方法时把注入进来的类写进去。
private static C C;
@Autowired
private C CTemp;
@PostConstruct
private void init() {
C = CTemp;
}
method1.invoke(C, param)