本文作为springboot注解Aspect文章的补充,切面拦截方法,将方法所有信息及服务名称持久化到数据库。
审批的时候,从数据库获取服务名称动态调用服务。
实体类
示例中的响应实体类
@Getter
@Setter
public class Response<T> {
private String code;
private String msg;
private String description;
private T data;
}
示例中的方法参数实体类
@Getter
@Setter
public class ProcessCheckDTO {
private ProcessCheckModel processCheckModel;
private MethodInfo methodInfo;
}
@Setter
@Getter
public class ProcessCheckModel {
/**
* 0-审批通过 1-审批拒绝
*/
private String checkType;
/**
* 审批拒绝原因
*/
private String reason;
}
拦截的方法实体类
@Getter
@Setter
public class MethodInfo {
//,项目名称
private String appName;
//bean的目标类全限定名
private String targetClassName;
//拦截到的service方法名
private String methodName;
//拦截到的service入参类型,包含泛型信息
private String paramTypes;
//拦截到的service入参值
private String paramArgs;
}
下面的才是最重要的
先写一个FeignCient接口
/**
* 接口上不需要任何注解
*/
public interface ProcessClientApi {
@PostMapping(value = "/processCheck", consumes = MediaType.APPLICATION_JSON_VALUE)
public Response<?> process(@RequestBody ProcessCheckDTO processCheckDTO);
}
再写一个Bean用来动态获取ProcessClientApi
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.openfeign.FeignClientBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class DynamicProcessFeign {
//缓存feignClient,提高客户端性能
private static volatile Map<String, ProcessClientApi> processMap = new HashMap<>();
private FeignClientBuilder feignClientBuilder;
public DynamicProcessFeign(@Autowired ApplicationContext appContext) {
this.feignClientBuilder = new FeignClientBuilder(appContext);
}
public ProcessClientApi getFeignClient(String seviceName) {
ProcessClientApi api = processMap.get(seviceName);
if (api != null) {
return api;
}
synchronized (DynamicProcessFeign.class) {
api = processMap.get(seviceName);
if (api != null) {
return api;
}
api = this.feignClientBuilder.forType(ProcessClientApi.class, seviceName).build();
processMap.put(seviceName, api);
}
return api;
}
}
使用
private void process(ProcessRecordExecuteVO vo) {
ProcessCheckDTO processCheckDTO = new ProcessCheckDTO();
ProcessCheckModel processCheckModel = new ProcessCheckModel();
processCheckModel.setCheckType(vo.getAccept());
processCheckModel.setReason(vo.getReason());
processCheckDTO.setProcessCheckModel(processCheckModel);
ProcessMethodInfo processMethodInfo = processMethodInfoMapper.selectById(vo.getBatchId());
if (processMethodInfo == null) {
throw new BizException("未找到数据");
}
MethodInfo methodInfo = new MethodInfo();
methodInfo.setAppName(processMethodInfo.getAppName());
methodInfo.setTargetClassName(processMethodInfo.getTargetClassName());
methodInfo.setMethodName(processMethodInfo.getMethodName());
methodInfo.setParamTypes(processMethodInfo.getParamTypes());
methodInfo.setParamArgs(processMethodInfo.getParamArgs());
processCheckDTO.setMethodInfo(methodInfo);
/*
* 下面的两行代码是动态调用服务的用法
*/
//传入服务名称获取对应的FeignClient
ProcessClientApi processClientApi = dynamicProcessFeign.getFeignClient(methodInfo.getAppName());
//通过OpenFeign调用远程服务
processClientApi.process(processCheckDTO);
}