DubboのReferenceBeanリモートインタフェースの実装をローカルにインスタンス化するプロセス
7998 ワード
なぜdubboのサービスを引用したのか不思議だったが@Referenceで引用できなかったのは、ReferenceBeanのおかげだった.
ソースコードは次のとおりです.
そしてReferenceConfigのget()メソッドに入りました
StubProxyFactoryWrapper implements ProxyFactoryを呼び出したgetProxy
続いてAbstractProxyFactory implements ProxyFactoryのgetProxyを呼び出した
最終呼び出し
ソースコードは次のとおりです.
@Bean
public ReferenceBean repaymentPlanServiceReferenceBean(){
ReferenceBean referenceBean = new ReferenceBean<>();
referenceBean.setInterface(PLRepaymentPlanService.class);
referenceBean.setCheck(false);
referenceBean.setValidation("true");
return referenceBean;
}
ReferenceBean InitializingBean afterPropertiesSet ,
public void afterPropertiesSet() throws Exception {
...
if (b != null && b.booleanValue()) {
getObject();
}
}
public Object getObject() throws Exception {
return get();
}
そしてReferenceConfigのget()メソッドに入りました
public synchronized T get() {
if (destroyed) {
throw new IllegalStateException("Already destroyed!");
}
if (ref == null) {
//
init();
}
return ref;
}
private void init() {
//...
ref = createProxy(map);
}
//
private T createProxy(Map map) {
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());
}
} else {
if (url != null && url.length() > 0) { // URL, URL , URL
String[] us = Constants.SEMICOLON_SPLIT_PATTERN.split(url);
if (us != null && us.length > 0) {
for (String u : us) {
URL url = URL.valueOf(u);
if (url.getPath() == null || url.getPath().length() == 0) {
url = url.setPath(interfaceName);
}
if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
urls.add(url.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));
} else {
urls.add(ClusterUtils.mergeUrl(url, map));
}
}
}
} else { // URL
List us = loadRegistries(false);
if (us != null && us.size() > 0) {
for (URL u : us) {
URL monitorUrl = loadMonitor(u);
if (monitorUrl != null) {
map.put(Constants.MONITOR_KEY, URL.encode(monitorUrl.toFullString()));
}
urls.add(u.addParameterAndEncoded(Constants.REFER_KEY, StringUtils.toQueryString(map)));
}
}
if (urls == null || urls.size() == 0) {
throw new IllegalStateException("No such any registry to reference " + interfaceName + " on the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion() + ", please config to your spring config.");
}
}
if (urls.size() == 1) {
invoker = refprotocol.refer(interfaceClass, urls.get(0));
} else {
List> invokers = new ArrayList>();
URL registryURL = null;
for (URL url : urls) {
invokers.add(refprotocol.refer(interfaceClass, url));
if (Constants.REGISTRY_PROTOCOL.equals(url.getProtocol())) {
registryURL = url; // registry url
}
}
if (registryURL != null) { // URL
// Cluster AvailableCluster
URL u = registryURL.addParameter(Constants.CLUSTER_KEY, AvailableCluster.NAME);
invoker = cluster.join(new StaticDirectory(u, invokers));
} else { // URL
invoker = cluster.join(new StaticDirectory(invokers));
}
}
}
Boolean c = check;
if (c == null && consumer != null) {
c = consumer.isCheck();
}
if (c == null) {
c = true; // default true
}
if (c && !invoker.isAvailable()) {
throw new IllegalStateException("Failed to check the status of the service " + interfaceName + ". No provider available for the service " + (group == null ? "" : group + "/") + interfaceName + (version == null ? "" : ":" + version) + " from the url " + invoker.getUrl() + " to the consumer " + NetUtils.getLocalHost() + " use dubbo version " + Version.getVersion());
}
if (logger.isInfoEnabled()) {
logger.info("Refer dubbo service " + interfaceClass.getName() + " from url " + invoker.getUrl());
}
//
return (T) proxyFactory.getProxy(invoker);
}
StubProxyFactoryWrapper implements ProxyFactoryを呼び出したgetProxy
public T getProxy(Invoker invoker) throws RpcException {
T proxy = proxyFactory.getProxy(invoker);
//...
return proxy;
}
続いてAbstractProxyFactory implements ProxyFactoryのgetProxyを呼び出した
public T getProxy(Invoker invoker) throws RpcException {
Class>[] interfaces = null;
String config = invoker.getUrl().getParameter("interfaces");
if (config != null && config.length() > 0) {
String[] types = Constants.COMMA_SPLIT_PATTERN.split(config);
if (types != null && types.length > 0) {
interfaces = new Class>[types.length + 2];
interfaces[0] = invoker.getInterface();
interfaces[1] = EchoService.class;
for (int i = 0; i < types.length; i++) {
interfaces[i + 1] = ReflectUtils.forName(types[i]);
}
}
}
if (interfaces == null) {
interfaces = new Class>[]{invoker.getInterface(), EchoService.class};
}
return getProxy(invoker, interfaces);
}
最終呼び出し
public class JavassistProxyFactory extends AbstractProxyFactory {
@SuppressWarnings("unchecked")
public T getProxy(Invoker invoker, Class>[] interfaces) {
//
return (T) Proxy.getProxy(interfaces).newInstance(new InvokerInvocationHandler(invoker));
}
public Invoker getInvoker(T proxy, Class type, URL url) {
// TODO Wrapper $
final Wrapper wrapper = Wrapper.getWrapper(proxy.getClass().getName().indexOf('$') < 0 ? proxy.getClass() : type);
return new AbstractProxyInvoker(proxy, type, url) {
@Override
protected Object doInvoke(T proxy, String methodName,
Class>[] parameterTypes,
Object[] arguments) throws Throwable {
return wrapper.invokeMethod(proxy, methodName, parameterTypes, arguments);
}
};
}
}