dubbo 版本 2.5.3
1.JVM可以直接配置对应interface的url 或者指定dubbo路径文件,格式参照properties
ReferenceConfig.class line 185
String resolve = System.getProperty(interfaceName);
String resolveFile = null;
if (resolve == null || resolve.length() == 0) {
resolveFile = System.getProperty("dubbo.resolve.file");
if (resolveFile == null || resolveFile.length() == 0) {
File userResolveFile = new File(new File(System.getProperty("user.home")), "dubbo-resolve.properties");
if (userResolveFile.exists()) {
resolveFile = userResolveFile.getAbsolutePath();
}
}
if (resolveFile != null && resolveFile.length() > 0) {
Properties properties = new Properties();
FileInputStream fis = null;
try {
fis = new FileInputStream(new File(resolveFile));
properties.load(fis);
} catch (IOException e) {
throw new IllegalStateException("Unload " + resolveFile + ", cause: " + e.getMessage(), e);
} finally {
try {
if(null != fis) fis.close();
} catch (IOException e) {
logger.warn(e.getMessage(), e);
}
}
resolve = properties.getProperty(interfaceName);
}
}
if (resolve != null && resolve.length() > 0) {
url = resolve;
if (logger.isWarnEnabled()) {
if (resolveFile != null && resolveFile.length() > 0) {
logger.warn("Using default dubbo resolve file " + resolveFile + " replace " + interfaceName + "" + resolve + " to p2p invoke remote service.");
} else {
logger.warn("Using -D" + interfaceName + "=" + resolve + " to p2p invoke remote service.");
}
}
}
2.这里是否走本地的相关判断没看懂
ReferenceConfig.class line 338
URL tmpUrl = new URL("temp", "localhost", 0, map);
final boolean isJvmRefer;
if (isInjvm() == null) {
if (url != null && url.length() > 0) { //指定URL的情况下,不做本地引用
isJvmRefer = false;
} else if (InjvmProtocol.getInjvmProtocol().isInjvmRefer(tmpUrl)) {
//默认情况下如果本地有服务暴露,则引用本地服务.
isJvmRefer = true;
} else {
isJvmRefer = false;
}
} else {
isJvmRefer = isInjvm().booleanValue();
}
if (isJvmRefer) {
URL url = new URL(Constants.LOCAL_PROTOCOL, NetUtils.LOCALHOST, 0, interfaceClass.getName()).addParameters(map);
invoker = refprotocol.refer(interfaceClass, url);
if (logger.isInfoEnabled()) {
logger.info("Using injvm service " + interfaceClass.getName());
}
}
public boolean isInjvmRefer(URL url) {
final boolean isJvmRefer;
String scope = url.getParameter(Constants.SCOPE_KEY);
//本身已经是jvm协议了,走正常流程就是了.
if (Constants.LOCAL_PROTOCOL.toString().equals(url.getProtocol())) {
isJvmRefer = false;
} else if (Constants.SCOPE_LOCAL.equals(scope) || (url.getParameter("injvm", false))) {
//如果声明为本地引用
//scope=local || injvm=true 等价 injvm标签未来废弃掉.
isJvmRefer = true;
} else if (Constants.SCOPE_REMOTE.equals(scope)){
//声明了是远程引用,则不做本地引用
isJvmRefer = false;
} else if (url.getParameter(Constants.GENERIC_KEY, false)){
//泛化调用不走本地
isJvmRefer = false;
} else if (getExporter(exporterMap, url) != null) {
//默认情况下如果本地有服务暴露,则引用本地服务.
isJvmRefer = true;
} else {
isJvmRefer = false;
}
return isJvmRefer;
}
3.异步dubbo调用如何实现值传递有一块看不懂
FutureFilter.class line 123
后来看了这篇文章就清楚了一些
https://blog.csdn.net/u013160932/article/details/81144471
private void fireReturnCallback(final Invoker<?> invoker, final Invocation invocation, final Object result) {
final Method onReturnMethod = (Method)StaticContext.getSystemContext().get(StaticContext.getKey(invoker.getUrl(), invocation.getMethodName(), Constants.ON_RETURN_METHOD_KEY));
final Object onReturnInst = StaticContext.getSystemContext().get(StaticContext.getKey(invoker.getUrl(), invocation.getMethodName(), Constants.ON_RETURN_INSTANCE_KEY));
//not set onreturn callback
if (onReturnMethod == null && onReturnInst == null ){
return ;
}
if (onReturnMethod == null || onReturnInst == null ){
throw new IllegalStateException("service:" + invoker.getUrl().getServiceKey() +" has a onreturn callback config , but no such "+(onReturnMethod == null ? "method" : "instance")+" found. url:"+invoker.getUrl());
}
if (onReturnMethod != null && ! onReturnMethod.isAccessible()) {
onReturnMethod.setAccessible(true);
}
Object[] args = invocation.getArguments();
Object[] params ;
Class<?>[] rParaTypes = onReturnMethod.getParameterTypes() ;
if (rParaTypes.length >1 ) {
if (rParaTypes.length == 2 && rParaTypes[1].isAssignableFrom(Object[].class)){
params = new Object[2];
params[0] = result;
params[1] = args ;
}else {
params = new Object[args.length + 1];
params[0] = result;
System.arraycopy(args, 0, params, 1, args.length);
}
} else {
params = new Object[] { result };
}
try {
onReturnMethod.invoke(onReturnInst, params);
} catch (InvocationTargetException e) {
fireThrowCallback(invoker, invocation, e.getTargetException());
} catch (Throwable e) {
fireThrowCallback(invoker, invocation, e);
}
}
4. 一些因引用了外部包(包含自定义dubbo filter)可以使用url里面增加key的方式去掉对应的filter
类似: reference.filter=-xxx.XXXX
ProtocolFilterWrapper.class
public <T> Invoker<T> refer(Class<T> type, URL url) throws RpcException {
return "registry".equals(url.getProtocol())?this.protocol.refer(type, url):buildInvokerChain(this.protocol.refer(type, url), "reference.filter", "consumer");
}
ExtensionLoader.class
public List<T> getActivateExtension(URL url, String key, String group) {
String value = url.getParameter(key);
return this.getActivateExtension(url, value != null && value.length() != 0?Constants.COMMA_SPLIT_PATTERN.split(value):null, group);
}
public List<T> getActivateExtension(URL url, String[] values, String group) {
List<T> exts = new ArrayList();
List<String> names = values == null?new ArrayList(0):Arrays.asList(values);
String name;
if(!((List)names).contains("-default")) {
this.getExtensionClasses();
Iterator i$ = this.cachedActivates.entrySet().iterator();
while(i$.hasNext()) {
Entry<String, Activate> entry = (Entry)i$.next();
name = (String)entry.getKey();
Activate activate = (Activate)entry.getValue();
if(this.isMatchGroup(group, activate.group())) {
T ext = this.getExtension(name);
if(!((List)names).contains(name) && !((List)names).contains("-" + name) && this.isActive(activate, url)) {
exts.add(ext);
}
}