前言
spring2.5以后,spring支持自定义schema扩展xml配置。具体的spring schema细节,本文就不多说了。这篇文章就拿provider为例,介绍dubbo是如何启动服务的。
正文
首先,再把HelloWolrd例子中的 provider.xml的源码放上来
Xml代码
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://code.alibabatech.com/schema/dubbo
- http://code.alibabatech.com/schema/dubbo/dubbo.xsd
- ">
- <dubbo:application name="hello-world-app" />
- <dubbo:registry protocol="zookeeper" address="10.125.195.174:2181" />
- <dubbo:protocol name="dubbo" port="20880" />
- <dubbo:service interface="demo.service.DemoService"
- ref="demoService" /> <!-- 和本地bean一样实现服务 -->
- <bean id="demoService" class="demo.service.DemoServiceImpl" />
- </beans>
对应的自定义schema文件,就不解释了。直接在dubbo-{version}.jar 中 META-INF目录下找到对应的handler配置
spring.handlers 写道
http\://code.alibabatech.com/schema/dubbo=com.alibaba.dubbo.config.spring.schema.DubboNamespaceHandler
可以看到,对应的handler是 DubboNamespaceHandler。对应的源码如下
Java代码
- public class DubboNamespaceHandler extends NamespaceHandlerSupport {
- static {
- Version.checkDuplicate(DubboNamespaceHandler.class);
- }
- public void init() {
- registerBeanDefinitionParser("application", new DubboBeanDefinitionParser(ApplicationConfig.class, true));
- registerBeanDefinitionParser("module", new DubboBeanDefinitionParser(ModuleConfig.class, true));
- registerBeanDefinitionParser("registry", new DubboBeanDefinitionParser(RegistryConfig.class, true));
- registerBeanDefinitionParser("monitor", new DubboBeanDefinitionParser(MonitorConfig.class, true));
- registerBeanDefinitionParser("provider", new DubboBeanDefinitionParser(ProviderConfig.class, true));
- registerBeanDefinitionParser("consumer", new DubboBeanDefinitionParser(ConsumerConfig.class, true));
- registerBeanDefinitionParser("protocol", new DubboBeanDefinitionParser(ProtocolConfig.class, true));
- registerBeanDefinitionParser("service", new DubboBeanDefinitionParser(ServiceBean.class, true));
- registerBeanDefinitionParser("reference", new DubboBeanDefinitionParser(ReferenceBean.class, false));
- registerBeanDefinitionParser("annotation", new DubboBeanDefinitionParser(AnnotationBean.class, true));
- }
- }
从这里也可以看到,对应的支持的标签其实不多。所有的Parser都封装到了DubboBeanDefinitionParser中。对应的class,就是传入的beanClass。比如application的就是ApplicationConfig。module的就是ModuleConfig。经过Parser的转换,provider.xml大概可以变成如下的样子(具体的解析不多解释了)
Xml代码
- <bean id="hello-world-app" class="com.alibaba.dubbo.config.ApplicationConfig"/>
- <bean id="registryConfig" class="com.alibaba.dubbo.config.RegistryConfig">
- <property name="address" value="10.125.195.174:2181"/>
- <property name="protocol" value="zookeeper"/>
- </bean>
- <bean id="dubbo" class="com.alibaba.dubbo.config.ProtocolConfig">
- <property name="port" value="20880"/>
- </bean>
- <bean id="demo.service.DemoService" class="com.alibaba.dubbo.config.spring.ServiceBean">
- <property name="interface" value="demo.service.DemoService"/>
- <property name="ref" ref="demoService"/>
- </bean>
- <bean id="demoService" class="demo.service.DemoServiceImpl" />
分别看每一个bean的内容。由于篇幅原因,我就不把每个代码放上来了。总结一下就是
写道
ApplicationConfig,RegistryConfig,ProtocolConfig都只是普通的pojo。负责接收数据。真正的处理逻辑在ServiceBean中
看具体的代码
Java代码
- public class ServiceBean<T> extends ServiceConfig<T> implements InitializingBean, DisposableBean, ApplicationContextAware, ApplicationListener, BeanNameAware {
- private static final long serialVersionUID = 213195494150089726L;
- private static transient ApplicationContext SPRING_CONTEXT;
- private transient ApplicationContext applicationContext;
- private transient String beanName;
- private transient boolean supportedApplicationListener;
- public ServiceBean() {
- super();
- }
- public ServiceBean(Service service) {
- super(service);
- }
- public static ApplicationContext getSpringContext() {
- return SPRING_CONTEXT;
- }
- //设置对应的applicationConext
- public void setApplicationContext(ApplicationContext applicationContext) {
- this.applicationContext = applicationContext;
- SpringExtensionFactory.addApplicationContext(applicationContext);
- if (applicationContext != null) {
- SPRING_CONTEXT = applicationContext;
- try {
- Method method = applicationContext.getClass().getMethod("addApplicationListener", new Class<?>[]{ApplicationListener.class}); // 兼容Spring2.0.1
- method.invoke(applicationContext, new Object[] {this});
- supportedApplicationListener = true;
- } catch (Throwable t) {
- if (applicationContext instanceof AbstractApplicationContext) {
- try {
- Method method = AbstractApplicationContext.class.getDeclaredMethod("addListener", new Class<?>[]{ApplicationListener.class}); // 兼容Spring2.0.1
- if (! method.isAccessible()) {
- method.setAccessible(true);
- }
- method.invoke(applicationContext, new Object[] {this});
- supportedApplicationListener = true;
- } catch (Throwable t2) {
- }
- }
- }
- }
- }
- public void setBeanName(String name) {
- this.beanName = name;
- }
- public void onApplicationEvent(ApplicationEvent event) {
- //如果容器加载完成以后当前的provider还没export,那么调用一次export方法(这个针对那种延迟export的情况)
- 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();
- }
- }
- }
- //是否延迟export
- private boolean isDelay() {
- Integer delay = getDelay();
- ProviderConfig provider = getProvider();
- if (delay == null && provider != null) {
- delay = provider.getDelay();
- }
- return supportedApplicationListener && (delay == null || delay.intValue() == -1);
- }
- @SuppressWarnings({ "unchecked", "deprecation" })
- public void afterPropertiesSet() throws Exception {
- //这里的Provider其实就是ProviderConfig对象。如果provider为空,表示spring在创建 当前bean的时候还没有初始化ProtocolConfig bean。这里就是做一个前后顺序保证
- if (getProvider() == null) {
- Map<String, ProviderConfig> providerConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProviderConfig.class, false, false);
- if (providerConfigMap != null && providerConfigMap.size() > 0) {
- Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
- if ((protocolConfigMap == null || protocolConfigMap.size() == 0)
- && providerConfigMap.size() > 1) { // 兼容旧版本
- List<ProviderConfig> providerConfigs = new ArrayList<ProviderConfig>();
- for (ProviderConfig config : providerConfigMap.values()) {
- if (config.isDefault() != null && config.isDefault().booleanValue()) {
- providerConfigs.add(config);
- }
- }
- if (providerConfigs.size() > 0) {
- setProviders(providerConfigs);
- }
- } else {
- ProviderConfig providerConfig = null;
- for (ProviderConfig config : providerConfigMap.values()) {
- if (config.isDefault() == null || config.isDefault().booleanValue()) {
- if (providerConfig != null) {
- throw new IllegalStateException("Duplicate provider configs: " + providerConfig + " and " + config);
- }
- providerConfig = config;
- }
- }
- if (providerConfig != null) {
- setProvider(providerConfig);
- }
- }
- }
- }
- //这里和上面同样,手动创建ApplicationConfig bean
- if (getApplication() == null
- && (getProvider() == null || getProvider().getApplication() == null)) {
- Map<String, ApplicationConfig> applicationConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ApplicationConfig.class, false, false);
- if (applicationConfigMap != null && applicationConfigMap.size() > 0) {
- ApplicationConfig applicationConfig = null;
- for (ApplicationConfig config : applicationConfigMap.values()) {
- if (config.isDefault() == null || config.isDefault().booleanValue()) {
- if (applicationConfig != null) {
- throw new IllegalStateException("Duplicate application configs: " + applicationConfig + " and " + config);
- }
- applicationConfig = config;
- }
- }
- if (applicationConfig != null) {
- setApplication(applicationConfig);
- }
- }
- }
- //如果没有创建module,则手动创建 module。 在HelloWorld例子中,没有用到module。
- if (getModule() == null
- && (getProvider() == null || getProvider().getModule() == null)) {
- Map<String, ModuleConfig> moduleConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ModuleConfig.class, false, false);
- if (moduleConfigMap != null && moduleConfigMap.size() > 0) {
- ModuleConfig moduleConfig = null;
- for (ModuleConfig config : moduleConfigMap.values()) {
- if (config.isDefault() == null || config.isDefault().booleanValue()) {
- if (moduleConfig != null) {
- throw new IllegalStateException("Duplicate module configs: " + moduleConfig + " and " + config);
- }
- moduleConfig = config;
- }
- }
- if (moduleConfig != null) {
- setModule(moduleConfig);
- }
- }
- }
- //初始化registiry
- if ((getRegistries() == null || getRegistries().size() == 0)
- && (getProvider() == null || getProvider().getRegistries() == null || getProvider().getRegistries().size() == 0)
- && (getApplication() == null || getApplication().getRegistries() == null || getApplication().getRegistries().size() == 0)) {
- Map<String, RegistryConfig> registryConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, RegistryConfig.class, false, false);
- if (registryConfigMap != null && registryConfigMap.size() > 0) {
- List<RegistryConfig> registryConfigs = new ArrayList<RegistryConfig>();
- for (RegistryConfig config : registryConfigMap.values()) {
- if (config.isDefault() == null || config.isDefault().booleanValue()) {
- registryConfigs.add(config);
- }
- }
- if (registryConfigs != null && registryConfigs.size() > 0) {
- super.setRegistries(registryConfigs);
- }
- }
- }
- //初始化monitor (HelloWorld例子中没有用到)
- if (getMonitor() == null
- && (getProvider() == null || getProvider().getMonitor() == null)
- && (getApplication() == null || getApplication().getMonitor() == null)) {
- Map<String, MonitorConfig> monitorConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, MonitorConfig.class, false, false);
- if (monitorConfigMap != null && monitorConfigMap.size() > 0) {
- MonitorConfig monitorConfig = null;
- for (MonitorConfig config : monitorConfigMap.values()) {
- if (config.isDefault() == null || config.isDefault().booleanValue()) {
- if (monitorConfig != null) {
- throw new IllegalStateException("Duplicate monitor configs: " + monitorConfig + " and " + config);
- }
- monitorConfig = config;
- }
- }
- if (monitorConfig != null) {
- setMonitor(monitorConfig);
- }
- }
- }
- //初始化protocol
- if ((getProtocols() == null || getProtocols().size() == 0)
- && (getProvider() == null || getProvider().getProtocols() == null || getProvider().getProtocols().size() == 0)) {
- Map<String, ProtocolConfig> protocolConfigMap = applicationContext == null ? null : BeanFactoryUtils.beansOfTypeIncludingAncestors(applicationContext, ProtocolConfig.class, false, false);
- if (protocolConfigMap != null && protocolConfigMap.size() > 0) {
- List<ProtocolConfig> protocolConfigs = new ArrayList<ProtocolConfig>();
- for (ProtocolConfig config : protocolConfigMap.values()) {
- if (config.isDefault() == null || config.isDefault().booleanValue()) {
- protocolConfigs.add(config);
- }
- }
- if (protocolConfigs != null && protocolConfigs.size() > 0) {
- super.setProtocols(protocolConfigs);
- }
- }
- }
- //设置服务名称。
- if (getPath() == null || getPath().length() == 0) {
- if (beanName != null && beanName.length() > 0
- && getInterface() != null && getInterface().length() > 0
- && beanName.startsWith(getInterface())) {
- setPath(beanName);
- }
- }
- //调用export
- if (! isDelay()) {
- export();
- }
- }
- //调用unexport
- public void destroy() throws Exception {
- unexport();
- }
- }
代码里面已经加了一些注释。虽然很长,逻辑还是很简单的。其中用到了spring的很多特性。非常值得我们学习。
很明显,下一篇就要介绍 核心的 export 和unexport方法了。