Dubbo源码学习整合Spring 容器实现服务优雅启动和停止
Posted Dream_it_possible!
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dubbo源码学习整合Spring 容器实现服务优雅启动和停止相关的知识,希望对你有一定的参考价值。
一、 将应用整合Spring
1. 扫描包
使用AnnotationConfigApplicationContext类应用包,指定包的根路径即可,该类会加载并扫描所有Spring容器应该扫描的被指定注解标记类, 比如被@Component、@Configuration注解标记的类。
// 5. 整合spring容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext("com.example.dubbo");
context.start();
包的路径需要保证正确,否则在扫描注解的时候会出现找不到的情况,因为后续需要借助ApplicaitonListener接口来启动server。
2. 添加ServerApplicationListener类
在Spring 监听器类接口ApplicationListener中新建线程启动server, ApplicationListener接口中有个onApplicationContext()方法,在Spring 容器启动时会被调用到。
需要使用@Component注解标记,否则不会被Spring 容器扫描到,onApplicationContext()方法也不会执行, 此处的@Component注解可以替换为@Configuration注解。
package com.example.dubbo.spring;
import com.example.dubbo.framework.Protocol;
import com.example.dubbo.framework.ProtocolFactory;
import com.example.dubbo.framework.URL;
import com.example.dubbo.protocol.ProtocolUtil;
import com.example.dubbo.protocol.dubbo.DubboProtocol;
import com.example.dubbo.protocol.dubbo.NettyServer;
import com.example.dubbo.protocol.http.HttpProtocol;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
/**
* @author bingbing
* @date 2021/5/18 0018 20:49
*/
@Component
public class ServerApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
// 此方法在spring 容器启动后执行
String protocolName = System.getProperty("protocol");
Protocol protocol = ProtocolUtil.getProtocolBySystemProperty(protocolName);
System.out.println("启动Server...");
new Thread(() -> {
protocol.start(new URL("127.0.01", 9090));
}).start();
System.out.println("Server启动成功!");
}
}
3. 添加ProtocolUtil类
根据启动参数的设定,选择使用哪个协议。
package com.example.dubbo.protocol;
import com.example.dubbo.framework.Protocol;
import com.example.dubbo.framework.ProtocolFactory;
import com.example.dubbo.protocol.dubbo.DubboProtocol;
import com.example.dubbo.protocol.http.HttpProtocol;
/**
* @author bingbing
* @date 2021/5/18 0018 20:33
*/
public class ProtocolUtil {
public static Protocol getProtocolBySystemProperty(String protocolName) {
Protocol protocol;
if ("dubbo".equals(protocolName)) {
protocol = ProtocolFactory.getProtocol(DubboProtocol.class);
} else if ("http".equals(protocolName)) {
protocol = ProtocolFactory.getProtocol(HttpProtocol.class);
} else {
throw new RuntimeException("参数错误!");
}
return protocol;
}
}
我们只需要将server的启动方法放到线程里就能启动容器,即完成了Spring 整合。
二、 添加钩子函数优雅管理服务
JVM 在停止时,会有一系列的钩子函数需要被执行完成,这些钩子函数执行完毕后,JVM才会真正的停止。
private static volatile boolean running = false;
通过同步块和volatile 关键字保证服务优雅地停止。
//优雅的关闭服务器,添加钩子函数,只有钩子函数都执行完毕后,JVM才会正式停止。
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
try {
context.stop();
System.out.println("服务器已关闭...");
} catch (Throwable e) {
}
synchronized (ProviderApplication.class) {
running = false;
ProviderApplication.class.notify();
}
}));
System.out.println("服务器已启动======");
synchronized (ProviderApplication.class) {
while (running) {
try {
ProviderApplication.class.wait();
} catch (Throwable e) {
e.printStackTrace();
}
}
}
重新启动服务提供者:
关闭服务:
至此,实现整合spring 容器。
以上是关于Dubbo源码学习整合Spring 容器实现服务优雅启动和停止的主要内容,如果未能解决你的问题,请参考以下文章
Dubbo源码学习系列 整合zookeeper注册中心并提供watcher机制
Dubbo实战 Dubbo+Zookeeper+Spring整合应用篇-Dubbo基于Zookeeper实现分布式服务(转)