最舒服的方式——dubbo泛化调用接口
公司新出一个项目,是做一个定时任务管理系统,前段时间做一个项目,但里面嵌套了n多服务,用jar包的形式调用dubbo接口已经无法满足业务需求,并且不能动态化的添加定时任务,所以这个dubbo正儿八经的功能该上场了。由于我们公司用的基本框架是springboot,那我来讲解一下基于springboot的dubbo泛化调用。
1.首先:在配置文件配置好application.properties关于dubbo的属性
## Dubbo 服务消费者配置
spring.aop.proxy-target-class=true
dubbo.application.name=scheduled-service
dubbo.protocol.name=dubbo
dubbo.protocol.port=21011
dubbo.provider.version=2.0.0
dubbo.provider.timeout=20000
dubbo.scan=com.oms
dubbo.consumer.check=false
dubbo.consumer.timeout=20000
dubbo.consumer.retries=0
dubbo.consumer.version=2.0.0
#dubbo-zookeeper地址
dubbo.registry.address=zookeeper://172.0.0.1:2181
2.配置DubboServiceFactory 类
package com.oms.common.utils;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.utils.ReferenceConfigCache;
import com.alibaba.dubbo.rpc.service.GenericService;
import org.springframework.beans.factory.annotation.Value;
import java.io.IOException;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Properties;
public class DubboServiceFactory implements Serializable {
private ApplicationConfig application;
private RegistryConfig registry;
private static class SingletonHolder {
private static DubboServiceFactory INSTANCE = new DubboServiceFactory();
}
private DubboServiceFactory(){
Properties prop = new Properties();
ClassLoader loader = DubboServiceFactory.class.getClassLoader();
try {
prop.load(loader.getResourceAsStream("application.properties"));
} catch (IOException e) {
e.printStackTrace();
}
ApplicationConfig applicationConfig = new ApplicationConfig();
//这里配置了dubbo的application信息,此3条信息是必须获取的基本信息
applicationConfig.setName(prop.getProperty("dubbo.application.name"));
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress(prop.getProperty("dubbo.registry.address"));
registryConfig.setVersion(prop.getProperty("dubbo.provider.version"));
this.application = applicationConfig;
this.registry = registryConfig;
}
public static DubboServiceFactory getInstance() {
return SingletonHolder.INSTANCE;
}
public Object genericInvoke(String interfaceClass, String methodName, List<Map<String, Object>> parameters){
ReferenceConfig<GenericService> reference = new ReferenceConfig<GenericService>();
reference.setApplication(application);
reference.setRegistry(registry);
//这个版本号也是必须设置的
reference.setVersion(registry.getVersion());
reference.setInterface(interfaceClass); // 接口名
reference.setGeneric(true); // 声明为泛化接口
/*ReferenceConfig实例很重,封装了与注册中心的连接以及与提供者的连接,
需要缓存,否则重复生成ReferenceConfig可能造成性能问题并且会有内存和连接泄漏。
API方式编程时,容易忽略此问题。
这里使用dubbo内置的简单缓存工具类进行缓存*/
ReferenceConfigCache cache = ReferenceConfigCache.getCache();
GenericService genericService =cache.get(reference);
// 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用
int len = parameters.size();
String[] invokeParamTyeps = new String[len];
Object[] invokeParams = new Object[len];
for(int i = 0; i < len; i++){
invokeParamTyeps[i] = parameters.get(i).get("ParamType") + "";
invokeParams[i] = parameters.get(i).get("Object");
}
return genericService.$invoke(methodName, invokeParamTyeps, invokeParams);
}
}
3.调用DubboServiceFactory 类里的方法
DubboServiceFactory dubbo = DubboServiceFactory.getInstance();
Object object=dubbo.genericInvoke("com.**.**", "方法名称", "参数");
写完以后,怎么感觉就这么简单???对,就这么简单。