dubbo-container-spring只有一个类,SpringContainer implements Container
SpringContainer
继承Container,有两个方法start和stop
/**
* SpringContainer. (SPI, Singleton, ThreadSafe)
*/
public class SpringContainer implements Container {
public static final String SPRING_CONFIG = "dubbo.spring.config";
public static final String DEFAULT_SPRING_CONFIG = "classpath*:META-INF/spring/*.xml";
private static final Logger logger = LoggerFactory.getLogger(SpringContainer.class);
static ClassPathXmlApplicationContext context;
public static ClassPathXmlApplicationContext getContext() {
return context;
}
@Override
public void start() {
String configPath = ConfigUtils.getProperty(SPRING_CONFIG);
if (configPath == null || configPath.length() == 0) {
configPath = DEFAULT_SPRING_CONFIG;
}
context = new ClassPathXmlApplicationContext(configPath.split("[,\\s]+"), false);
// 注册容器监听,用于暴露service和清理service
context.addApplicationListener(new DubboApplicationListener());
context.registerShutdownHook();
context.refresh();
context.start();
}
@Override
public void stop() {
try {
if (context != null) {
context.stop();
context.close();
context = null;
}
} catch (Throwable e) {
logger.error(e.getMessage(), e);
}
}
}
关键代码,context.addApplicationListener(new DubboApplicationListener());我们看下DubboApplicationListener。
/**
* An application listener that listens the ContextClosedEvent.
* Upon the event, this listener will do the necessary clean up to avoid memory leak.
*/
public class DubboApplicationListener implements ApplicationListener<ApplicationEvent> {
private DubboBootstrap dubboBootstrap;
public DubboApplicationListener() {
dubboBootstrap = new DubboBootstrap(false);
}
public DubboApplicationListener(DubboBootstrap dubboBootstrap) {
this.dubboBootstrap = dubboBootstrap;
}
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
if (applicationEvent instanceof ContextRefreshedEvent) {
// 暴露service
dubboBootstrap.start();
} else if (applicationEvent instanceof ContextClosedEvent) {
// 清理service
dubboBootstrap.stop();
}
}
}
DubboBootstrap.java
public void start() {
if (registerShutdownHookOnStart) {
registerShutdownHook();
} else {
// DubboShutdown hook has been registered in AbstractConfig,
// we need to remove it explicitly
removeShutdownHook();
}
for (ServiceConfig serviceConfig: serviceConfigList) {
serviceConfig.export();
}
}
public void stop() {
for (ServiceConfig serviceConfig: serviceConfigList) {
serviceConfig.unexport();
}
shutdownHook.destroyAll();
if (registerShutdownHookOnStart) {
removeShutdownHook();
}
}