Dubbo服务发布流程(服务bean的定义、创建、初始化、服务暴露、网络监听)

先上简易结论:针对一个服务发布是在底层打开socket监听端口(默认netty),接受请求时解析请求参数(请求接口,请求方法,请求参数)去获取接口实现类的动态代理,根据反射调用实现类方法,然后(通过网络)返回请求结果给调用方

dubbo是无缝接入spring的,也因此借着spring的特性去实现一些服务发布需要做的事情(ioc实例化自定义的bean、容器初始化后进行服务发布)

1.服务发布bean的定义、初始化
定义一个服务发布需要在xml(官方推荐用xml配置dubbo)定义下面内容:

<bean id="demoService" class="com.alibaba.dubbo.demo.provider.DemoServiceImpl"/>

<dubbo:service interface="com.alibaba.dubbo.demo.DemoService" ref="demoService"/>

很明显,以上<bean>标签能由spring处理后作为一个bean在容器注册,但<dubbo:service>标签是spring不能处理的,所以由dubbo"告诉"spring应该怎么处理
dubbo有个DubboNamespaceHandler类,继承了spring的NamespaceHandlerSupport(命名空间解析),往解析器列表中加入能解析dubbo标签的解析器

public class DubboNamespaceHandler extends NamespaceHandlerSupport {
   

    static {
   
        Version.checkDuplicate(DubboNamespaceHandler.class);
    }

    @Override
    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 AnnotationBeanDefinitionParser());
    }
}

在初始化方法调用父类NamespaceHandlerSupport方法registerBeanDefinitionParser(),代码如下:

private final Map<String, BeanDefinitionParser> parsers = new HashMap<String, BeanDefinitionParser>();

protected final void registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser) {
   
		this.parsers.put(elementName, parser);
}

所以dubbo往spring解析器列表(parsers)中加入能处理特定命名空间的dubbo标签(service、reference等)的解析器DubboBeanDefinitionParser,这样spring在读取xml解析标签时遇到dubbo的标签就会调用相应的解析器的parse()方法去解析
接下来查看DubboBeanDefinitionParser的构造以及重要的解析方法parse()

public class DubboBeanDefinitionParser implements BeanDefinitionParser {
   

    private final Class<?> beanClass;
    private final boolean required;
    
	/**
	 * beanClass:在DubboNamespaceHandler中传进来的Class,即把标签和Class对应起来,这里例子指的是ServiceBean.class
	 * <dubbo:service> ---解析为--- ServiceBean
	 */
    public DubboBeanDefinitionParser(Class<?> beanClass, boolean required) {
   
        this.beanClass = beanClass;
        this.required = required;
    }
    
	@Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
   
        return parse(element, parserContext, beanClass, required);
    }

    @SuppressWarnings("unchecked")
    private static BeanDefinition parse(Element element, ParserContext parserContext, Class<?> beanClass, boolean required) {
   
        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        ......
        if (ServiceBean.class.equals(beanClass)) {
   
            String className = element.getAttribute("class");
            if (className != null && className.length() > 0) {
   
                RootBeanDefinition classDefinition = new RootBeanDefinition();
                classDefinition.setBeanClass(ReflectUtils.forName(className));
                classDefinition.setLazyInit(false);
                parseProperties(element.getChildNodes(), classDefinition);
                beanDefinition.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl"));
        }
        ......
        //把传进来的标签element里的属性(如id、interface、class等)设置给beanDefinition
        //根据beanClass(ServiceBean)获取set方法放进beanDefinition记录着
        return beanDefinition;
    }
}

上面代码是spring初始化遇到dubbo标签时会执行的代码,这里beanDefinition的定义是记录着需要实例化bean的各种信息,相当于模子,有了模子就可以实例化相应的bean出来,返回的beanDefinition最终会放到spring一个beanDefinitionMap<String, BeanDefinition>中,其中key为xml定义的id
spring容器初始化期间会调用如下的代码:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
		implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
   
	
	
	@Override
	public void preInstantiateSingletons() throws BeansException {
   
		// 实例化非懒加载的单例bean
		
		// 获取beanName列表
		List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);

		// 遍历beanName列表调用getBean(beanName)实例化bean
		for (String beanName : beanNames) {
   
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
   
				......
				getBean(beanName)
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值