这段时间学习了下公司关于dubbo的使用,以API的形式接入dubbo服务
1、通过加载poperties的形式将系统的配置 信息加载到System环境变量中
2、通过@Bean的形式注册duboo的基础配置信息ApplicationConfig、RegistryConfig、ProtocolConfig、ProviderConfig、ConsumerConfig等信息
3、而服务的暴露和引用则可以通过
private Object referService(Object bean,Class> referenceClass, SIGroup siGroup) {
String interfaceName;
if (referenceClass.isInterface()) {
interfaceName = referenceClass.getName();
} else {
throw new IllegalStateException("The @Reference undefined interfaceClass or interfaceName, and the property type "
+ referenceClass.getName() + " is not a interface.");
}
String key = "/" + interfaceName + Constants.V_TUBE_PROXY_SUFFIX + ":";
ReferenceBean> referenceConfig = referenceConfigs.get(key);
if (referenceConfig == null) {
referenceConfig = new ReferenceBean();
referenceConfig.setLazy(true);
referenceConfig.setFilter("-exception,tubeContext,tubeException,tubeLog");
if (applicationContext.getEnvironment().containsProperty(Constants.TUBE_DUBBO_CONSUMER_CHECK)) {
Boolean check = Boolean.parseBoolean(env.getProperty(Constants.TUBE_DUBBO_CONSUMER_CHECK));
referenceConfig.setCheck(check);
}
if (siGroup != null) {
if (!StringUtil.isBlank(siGroup.value())) {
referenceConfig.setGroup(siGroup.value());
} else {
String groupName = "";
if( bean instanceof DubboGroupLoader) {
DubboGroupLoader dubboGroupLoader = (DubboGroupLoader) bean;
groupName = dubboGroupLoader.loadGroupName();
} else {
DubboGroupLoader dubboGroupLoader = getDubboGroupLoader();
if(dubboGroupLoader != null) {
groupName = dubboGroupLoader.loadGroupName();
}
}
if (!StringUtil.isBlank(groupName)) {
referenceConfig.setGroup(groupName);
}
}
}
referenceConfig.setInterface(referenceClass);
referenceConfig.setProtocol("dubbo");
if (applicationContext != null) {
referenceConfig.setApplicationContext(applicationContext);
try {
referenceConfig.afterPropertiesSet();
} catch (RuntimeException e) {
throw (RuntimeException) e;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
referenceConfigs.putIfAbsent(key, referenceConfig);
referenceConfig = referenceConfigs.get(key);
}
return referenceConfig.get();
}
通过手动的方式实现服务消费者的引入
public synchronized void exportService() {
if (entrustbean == null) {
entrustbean = TubeAnnotationBean.this.createSIBean(targetOject, targetClass);
}
entrustbean.doExport();
}
private SIBean createSIBean(Object bean, Class> clazz) {
SI service = clazz.getAnnotation(SI.class);
SIGroup siGroup = clazz.getAnnotation(SIGroup.class);
if (service != null) {
Class> intefaceClass = clazz.getInterfaces()[0];
SIBean serviceConfig = new SIBean();
serviceConfig.setInterface(intefaceClass);
serviceConfig.setRef(bean);
serviceConfig.setFilter("-exception,tubeContext,tubeException,tubeLog");
if (siGroup != null) {
if (!StringUtil.isBlank(siGroup.value())) {
serviceConfig.setGroup(siGroup.value());
} else {
String groupName = "";
if( bean instanceof DubboGroupLoader) {
DubboGroupLoader dubboGroupLoader = (DubboGroupLoader) bean;
groupName = dubboGroupLoader.loadGroupName();
} else {
DubboGroupLoader dubboGroupLoader = getDubboGroupLoader();
if(dubboGroupLoader != null) {
groupName = dubboGroupLoader.loadGroupName();
}
}
if (!StringUtil.isBlank(groupName)) {
serviceConfig.setGroup(groupName);
}
}
}
if (applicationContext != null) {
serviceConfig.setApplicationContext(applicationContext);
try {
serviceConfig.afterPropertiesSet();
} catch (RuntimeException e) {
throw (RuntimeException) e;
} catch (Exception e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
if (!StringUtil.isBlank(service.cluster())) {
serviceConfig.setCluster(service.cluster());
} else if (env.containsProperty(Constants.TUBE_DUBBO_CLUSTER)) {
serviceConfig.setCluster(env.getProperty(Constants.TUBE_DUBBO_CLUSTER));
}
if (service.retries() > 0) {
serviceConfig.setRetries(service.retries());
} else if (env.containsProperty(Constants.TUBE_DUBBO_RETRIES)) {
serviceConfig.setRetries(Integer.parseInt(env.getProperty(Constants.TUBE_DUBBO_RETRIES)));
}
return serviceConfig;
}
return null;
}
也以手动的形式向zookeper暴露服务
其中通过对dubbo服务的引用与在服务中注入,发现实际在consumer端中服务的,服务接口的引用指向并不是我们通常理解的接口实现类(***Impl),引用的指向而是一个Proxy代理类。在通过代理的handle去执行调用远程服务,通过指定ip以及端口进行远程,而服务(clazz),方法(mothd),参数(param),都是进行远程调用需要的参数
其中消费者端的引用指向的获取方式是通过ReferenceBean.get() 获取一个远程服务的bean。
最终指向的对象是 (T) proxyFactory.getProxy(invoker);
而invoker (com.alibaba.dubbo.rpc.cluster.support.wrapperMockClusterInvoker)是最终调用服务执行的代码块,
MockClusterInvoker.invoker()
通过设置debug断点,可以发现当我们进行dubbo服务调用时会这些下面的这样的代码
因此dubbo的核心理论我觉得是通过proxy的方法,代理执行各个远程服务接口的核心流程 。从而进行dubbo服务生态的展开其中包括注册机制zookeper,dubbo-admin,monitor,service-export,filter等组件。以及其他的dubbo项目的接入方式包括xml,@注解,api的方式,实现与spring框架的整合(主要是围绕着spring容器中针对bean的管理 )