利用Dubbo的SPI扩展容器
一、Dubbo的内置容器
二、自定义Container
2.1、首先用idea新建一个基于maven的java项目,添加dubbo,zk等依赖,具体的项目创建过程略过。
2.2、写一个接口和实现类,用来对外暴露
2.3、添加spring配置文件,dubbo配置文件等
2.4、定义一个容器类,实现Container接口
package com.ayo;
import com.alibaba.dubbo.container.Container;
import com.ayo.util.PathUtil;
import org.springframework.context.support.FileSystemXmlApplicationContext;
/**
* 自定义一个容器
*/
public class CustomContainer implements Container{
/**
* spring容器上下文
*/
static FileSystemXmlApplicationContext context;
/**
* 启动容器
*/
public void start() {
try {
String path = PathUtil.getAppConfPath().concat(PathUtil.sp()).concat("spring.xml");
context = new FileSystemXmlApplicationContext(path);
}catch (Exception e){
e.printStackTrace();
}
}
/**
* 停止容器
*/
public void stop() {
try {
if (context != null){
context.stop();
context.close();
context = null;
}
}catch (Exception e){
e.printStackTrace();
}
}
}
2.5、在resources下建一个文件夹命名为META-INF,然后在META-INF下再建一个文件夹命名为dubbo,然后建立一个文件命名为com.alibaba.dubbo.container.Container,里面写上内容
2.6、写一个Main类用于加载和启动自定义的Container
package com.ayo;
import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.container.Container;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 自定义dubbo容器
*
* @author ayo
*/
public class Main {
/**
* dubbo优雅关机
*/
public static final String SHUTDOWN_HOOK_KEY = "dubbo.shutdown.hook";
private static volatile boolean running = true;
public static void main(String[] args) {
try {
final Container customContainer = ExtensionLoader.getExtensionLoader(Container.class).getExtension("custom");
//在dubbo优雅关机的时候会触发此钩子函数
if ("true".equals(System.getProperty(SHUTDOWN_HOOK_KEY))) {
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
try {
customContainer.stop();
System.out.println("Dubbo " + customContainer.getClass().getSimpleName() + " stopped!");
} catch (Throwable t) {
t.printStackTrace();
}
synchronized (Main.class) {
running = false;
Main.class.notify();
}
}
});
}
customContainer.start();
System.out.println("Dubbo " + customContainer.getClass().getSimpleName() + " started!");
System.out.println(new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]").format(new Date()) + " Dubbo service server started!");
} catch (RuntimeException e) {
e.printStackTrace();
System.exit(1);
}
synchronized (Main.class) {
while (running) {
try {
Main.class.wait();
} catch (Throwable e) {
}
}
}
}
}
2.7、运行Main类中的main方法
2.8、看下服务有没有注册到zk
2.9、写个dubbo消费者测试下接口是否正常
package com.ayo;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.ayo.service.UserService;
public class Consumer {
public static void main(String[] args) {
//1.创建服务引用对象实例
ReferenceConfig<UserService> referenceConfig = new ReferenceConfig<UserService>();
//2.设置应用程序信息
ApplicationConfig applicationConfig = new ApplicationConfig("dubbo-consumer");
referenceConfig.setApplication(applicationConfig);
//3.设置服务注册中心
RegistryConfig registryConfig = new RegistryConfig("zookeeper://192.168.209.129:2181");
referenceConfig.setRegistry(registryConfig);
//3.设置服务接口和超时时间
referenceConfig.setInterface(UserService.class);
referenceConfig.setTimeout(5000);
//5.引用服务
UserService userService = referenceConfig.get();
//6.调用服务
System.out.println(userService.getUserName());
}
}