容器总览
通过配置文件dubbo.properties配置dubbo的容器(container):
#dubbo.properties配置log4j,spring容器组件,dubbo在启动时会初始化组件
dubbo.container=log4j,spring
#spring容器加载的配置文件,多个文件可以用','分隔
dubbo.spring.config=classpath:dubbo-lam-provider.xml
#dubbo服务的注册中心zookeeper配置
dubbo.registry.address=zookeeper://192.168.20.112:2181
#jetty容器监听端口,默认8080
dubbo.jetty.port=8080
#jetty的resources配置值
dubbo.jetty.directory=
#jetty的pages配置值
dubbo.jetty.page=
此外,有
jetty,log4j,logback,spring,registry
jetty=com.alibaba.dubbo.container.jetty.JettyContainer
log4j=com.alibaba.dubbo.container.log4j.Log4jContainer
logback=com.alibaba.dubbo.container.logback.LogbackContainer
spring=com.alibaba.dubbo.container.spring.SpringContainer
registry=com.alibaba.dubbo.monitor.simple.RegistryContainer
容器接口
@SPI("spring")
public interface Container {
void start();
void stop();
}
获取默认的容器,从上面接口Container可以知道spring是默认的容器
final SPI defaultAnnotation = type.getAnnotation(SPI.class);
if(defaultAnnotation != null) {
String value = defaultAnnotation.value();
if(value != null && (value = value.trim()).length() > 0) {
String[] names = NAME_SEPARATOR.split(value);
if(names.length > 1) {
throw new IllegalStateException("more than 1 default extension name on extension " + type.getName()
+ ": " + Arrays.toString(names));
}
if(names.length == 1) cachedDefaultName = names[0];
}
}
通过java命令参数-Ddubbo.shutdown.hook=true可以在虚拟机退出之前执行stop方法
Spring容器SpringContainer启动时会初始Spring配置文件
Spring的配置文件通过dubbo.spring.config来配置
dubbo标签
Dubbo通过对spring提供的自定义标签进行扩展
配置自定义标签的处理类
/dubbo-config-spring/src/main/resources/META-INF/spring.handlers:
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
自定义标签的XSD配置在/dubbo-config-spring/src/main/resources/META-INF/spring.schemas:
http\://code.alibabatech.com/schema/dubbo/dubbo.xsd=META-INF/dubbo.xsd
建立自定义标签的解析类
public class DubboBeanDefinitionParser implements BeanDefinitionParser {
public BeanDefinition parse(Element element, ParserContext parserContext) {
return parse(element, parserContext, beanClass, required);
}
}
parse方法里根据自定义标签对应的beanClass(如<dubbo:service/>标签对应ServiceBean.class)的get,set方法得到beanClass的属性,也就是对应自定义标签的属性,
从而对beanClass的属性进行赋值。
建立自定义标签的处理类,来调用解析类
public class DubboNamespaceHandler extends NamespaceHandlerSupport {
public void init() {
registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
//类似的还有module,registry,provider,consumer,protocol
registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
//类似的还有reference,annotation
}
}
其中ServiceBean.class就是对应服务提供者的<dubbo:service />标签,用来定义提供者暴露的接口服务
在Spring加载配置文件时,由于dubbo实现了Spring的ApplicationListener接口,可以加载dubbo的一些自定义bean标签,会触发事件。
com.alibaba.dubbo.config.spring.ServiceBean<T>
extends ServiceConfig<T>
implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware{
//实现接口ApplicationListener的方法
public void onApplicationEvent(ApplicationEvent event) {
if (ContextRefreshedEvent.class.getName().equals(event.getClass().getName())) {
if (isDelay() && ! isExported() && ! isUnexported()) {
if (logger.isInfoEnabled()) {
logger.info("The service ready on spring started. service: " + getInterface());
}
export();
}
}
}
}
ServiceConfig实现ApplicationListener接口的onApplicationEvent(ApplicationEvent event)方法,
监听Spring初始化或refresh时的事件发生时,初始化dubbo的service bean就,就进行暴露service的处理,具体见方法export()。
通过dubbo的启动日志(见下面),可以看出初始化自定义标签这步的执行:
com.alibaba.dubbo.config.AbstractConfig - [DUBBO] The service ready on spring started. service: xx.xxService, dubbo version: 2.5.3, current host: 127.0.0.1
自己写了个RPC:
可以给个star, ^-^。