最近做项目遇到一个问题,和spring扫描controller类似,由于请求都会到一个接口上,所以需要进行分发,当然可以自己写if判断进行处理,但是现在有了更好的处理方式了。
/**
* 扫描公共API
*/
@Configuration
public class ScannerOpenApi implements InitializingBean {
@Autowired
private ApplicationContext applicationContext;
@Autowired
private OpenApiHandler openApiHandler;
@Override
public void afterPropertiesSet() {
String[] beanNames = applicationContext.getBeanNamesForType(Object.class);
for (String beanName : beanNames) {
Class<?> handlerType = applicationContext.getType(beanName);
final Class<?> userType = ClassUtils.getUserClass(handlerType);
HandlerMethodSelector.selectMethods(userType, new ReflectionUtils.MethodFilter() {
public boolean matches(Method method) {
return filter(method, userType);
}
});
}
}
public boolean filter(Method method, Class<?> aClass) {
OpanApi methodAnnotation = AnnotationUtils.findAnnotation(method, OpanApi.class);
if (methodAnnotation != null) {
openApiHandler.putService(methodAnnotation.messageType(), methodAnnotation.messageCode(), aClass, method);
return true;
}
return false;
}
}
OpenApiHandler为处理转发的方法
@Service
public class OpenApiHandler {
private Logger logger = LoggerFactory.getLogger(OpenApiHandler.class);
private Map<String, ApiBean> handlerMap = new HashMap<>();
@Autowired
private ApplicationContext applicationContext;
/**
* 执行openApi服务
*
* @param inetCoreRequestMessage
* @return
*/
public OpenApiResponse handler(Map<String,Object> body) {
String messageType = body.get("messageType") + "";
String messageCode = body.get("messageCode") + "";
Object body = body.get("busBody");
OpenApiResponse response = new OpenApiResponse();
try {
Object object = getOpenApiService(messageType, messageCode).invoke(body);
if (object instanceof OpenApiResponse) {
return (OpenApiResponse) object;
}
response.setRespBody(object);
response.setRetCode("000000");
response.setRetMsg("交易成功");
response.setRetStatus("N");
} catch (Exception e) {
logger.error("执行失败:messageType={},messCode={}", messageType, messageCode, e);
if (e instanceof BusiException) {
response.setRetCode(((BusiException) e).getCode());
response.setRetMsg(((BusiException) e).getMsg());
} else {
response.setRetCode("999999");
response.setRetMsg("系统异常");
}
response.setRetStatus("E");
}
return response;
}
private ApiBean getOpenApiService(String messageType, String messageCode) {
return handlerMap.get(getKey(messageType, messageCode));
}
/**
* 添加OpenApi服务
*
* @param messageType
* @param messageCode
* @param method
*/
public void putService(String messageType, String messageCode, Class<?> cls, Method method) {
Object object = applicationContext.getBean(cls);
logger.info("open api [{}-{}]->{}", messageType, messageCode, cls.getClass().getName() + "." + method.getName());
handlerMap.put(getKey(messageType, messageCode), new ApiBean(object, method));
}
private String getKey(String messageType, String messageCode) {
return messageType + "-" + messageCode;
}
private class ApiBean {
private Object object;
private Method method;
public ApiBean(Object object, Method method) {
this.object = object;
this.method = method;
}
public Object getObject() {
return object;
}
public void setObject(Object object) {
this.object = object;
}
public OpenApiResponse invoke(Object arg) {
try {
return (OpenApiResponse) method.invoke(object, arg);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
}
使用的时候就简单了
@Service
public class DefOpenApiService {
private Logger logger = LoggerFactory.getLogger(getClass());
@OpanApi(messageType = "user", messageCode = "userMsg")
public Object userMsg(Object body) {
logger.info("接到请求:{}", JSONObject.fromObject(body).toString());
return null;
}
}
之所以这么做就是因为框架愿意请求只能是post方式,且已经指定了一个接口,只能通过请求中的messageType和messageCode确定具体业务,所以通过自定义注解的方式来实现解耦,方便开发,不喜勿喷,有用就帮忙点个赞吧