环境搭建
dubbo运行插件查看 Soul源码阅读 体验dubbo代理【第三天】
执行流程
GlobalPlugin -> BodyParamPlugin [org.dromara.soul.plugin.alibaba.dubbo.param] -> BodyParamPlugin [org.dromara.soul.plugin.sofa.param] 经过这一层但是是无效的 -> AbstractSoulPlugin-> AlibabaDubboPlugin ->DubboResponsePlugin -> 结束
alibab-dubbo 代码解析
BodyParamPlugin [org.dromara.soul.plugin.alibaba.dubbo.param]
@Override
// dubbo参数解析
public Mono execute(final ServerWebExchange exchange, final SoulPluginChain chain) {
// 请求信息
final ServerHttpRequest request = exchange.getRequest();
// Soul上下文
final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
// 如果是Dubbo的参数进行解析
if (Objects.nonNull(soulContext) && RpcTypeEnum.DUBBO.getName().equals(soulContext.getRpcType())) {
// 获取请求类型
MediaType mediaType = request.getHeaders().getContentType();
// webflux请求
ServerRequest serverRequest = ServerRequest.create(exchange, messageReaders);
// json请求
if (MediaType.APPLICATION_JSON.isCompatibleWith(mediaType)) {
return body(exchange, serverRequest, chain);
}
// 表单请求
if (MediaType.APPLICATION_FORM_URLENCODED.isCompatibleWith(mediaType)) {
return formData(exchange, serverRequest, chain);
}
// 塞入转换后的参数信息
return query(exchange, serverRequest, chain);
}
return chain.execute(exchange);
}
AlibabaDubboPlugin
@Override
// 执行dubbo调用
protected Mono doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
// 获取之前解析的参数信息
String body = exchange.getAttribute(Constants.DUBBO_PARAMS);
// Soul上下文
SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
assert soulContext != null;
// 获取元数据
MetaData metaData = exchange.getAttribute(Constants.META_DATA);
// 元数据有问题,返回错误信息
if (!checkMetaData(metaData)) {
assert metaData != null;
log.error(" path is :{}, meta data have error.... {}", soulContext.getPath(), metaData.toString());
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
Object error = SoulResultWrap.error(SoulResultEnum.META_DATA_ERROR.getCode(), SoulResultEnum.META_DATA_ERROR.getMsg(), null);
return WebFluxResultUtils.result(exchange, error);
}
// 参数类型和参数无数据,返回错误信息
if (StringUtils.isNoneBlank(metaData.getParameterTypes()) && StringUtils.isBlank(body)) {
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
Object error = SoulResultWrap.error(SoulResultEnum.DUBBO_HAVE_BODY_PARAM.getCode(), SoulResultEnum.DUBBO_HAVE_BODY_PARAM.getMsg(), null);
return WebFluxResultUtils.result(exchange, error);
}
// 执行请求
Object result = alibabaDubboProxyService.genericInvoker(body, metaData);
if (Objects.nonNull(result)) {
exchange.getAttributes().put(Constants.DUBBO_RPC_RESULT, result);
} else {
exchange.getAttributes().put(Constants.DUBBO_RPC_RESULT, Constants.DUBBO_RPC_RESULT_EMPTY);
}
exchange.getAttributes().put(Constants.CLIENT_RESPONSE_RESULT_TYPE, ResultEnum.SUCCESS.getName());
return chain.execute(exchange);
}
AlibabaDubboPlugin使用AlibabaDubboProxyService执行泛化调用
/**
* Generic invoker object.
*
* @param body the body
* @param metaData the meta data
* @return the object
* @throws SoulException the soul exception
*/
// 根据参数信息和元数据信息执行泛化调用
public Object genericInvoker(final String body, final MetaData metaData) throws SoulException {
// 从缓存中获取引用?
ReferenceConfig reference = ApplicationConfigCache.getInstance().get(metaData.getPath());
// 如果缓存中无值,进行初始化
if (Objects.isNull(reference) || StringUtils.isEmpty(reference.getInterface())) {
ApplicationConfigCache.getInstance().invalidate(metaData.getPath());
reference = ApplicationConfigCache.getInstance().initRef(metaData);
}
// 获取泛化调用服务
GenericService genericService = reference.get();
try {
Pair pair;
if (ParamCheckUtils.dubboBodyIsEmpty(body)) {
pair = new ImmutablePair<>(new String[]{}, new Object[]{});
} else {
// 解析值
pair = dubboParamResolveService.buildParameter(body, metaData.getParameterTypes());
}
// 泛化调用
return genericService.$invoke(metaData.getMethodName(), pair.getLeft(), pair.getRight());
} catch (GenericException e) {
log.error("dubbo invoker have exception", e);
throw new SoulException(e.getExceptionMessage());
}
}
DubboResponsePlugin 返回dubbo调用返回的值
/**
* Process the Web request and (optionally) delegate to the next
* {@code WebFilter} through the given {@link SoulPluginChain}.
*
* @param exchange the current server exchange
* @param chain provides a way to delegate to the next filter
* @return {@code Mono} to indicate when request processing is complete
*/
@Override
// 封装返回数据
public Mono execute(final ServerWebExchange exchange, final SoulPluginChain chain) {
return chain.execute(exchange).then(Mono.defer(() -> {
final Object result = exchange.getAttribute(Constants.DUBBO_RPC_RESULT);
try {
if (Objects.isNull(result)) {
Object error = SoulResultWrap.error(SoulResultEnum.SERVICE_RESULT_ERROR.getCode(), SoulResultEnum.SERVICE_RESULT_ERROR.getMsg(), null);
return WebFluxResultUtils.result(exchange, error);
}
Object success = SoulResultWrap.success(SoulResultEnum.SUCCESS.getCode(), SoulResultEnum.SUCCESS.getMsg(), JsonUtils.removeClass(result));
return WebFluxResultUtils.result(exchange, success);
} catch (SoulException e) {
return Mono.empty();
}
}));
}
apache dubbo
pom依赖
org.dromara
soul-spring-boot-starter-plugin-apache-dubbo
${project.version}
org.apache.dubbo
dubbo
2.7.5
org.apache.curator
curator-client
4.0.1
org.apache.curator
curator-framework
4.0.1
org.apache.curator
curator-recipes
4.0.1
调用流程
GlobalPlugin -> BodyParamPlugin[org.dromara.soul.plugin.apache.dubbo.param] -> BodyParamPlugin[org.dromara.soul.plugin.sofa.param] -> AbstractSoulPlugin -> ApacheDubboPlugin -> DubboResponsePlugin
ApacheDubboProxyService 主要泛化调用不同
/**
* Generic invoker object.
*
* @param body the body
* @param metaData the meta data
* @param exchange the exchange
* @return the object
* @throws SoulException the soul exception
*/
// apacheDubbo泛化调用
public Mono