07.提供者provider bean构建逻辑

Server 侧demo

启动类

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/com/code260/ss/dubbo/demov/server/conf/registercenter/zookeeper/applicationContextNode1.xml")
public class HelloServiceTestNode1
{

    @Test
    public void testSayHello()
    {
        try
        {
            System.out.println("zookeeper注册中心demo:I am node1:-)");
            System.in.read();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}

服务配置

<dubbo:service interface="com.code260.ss.dubbo.demov.facade.service.HelloService" ref="m00001.app001.xx.helloService" filter="tpslimiter" connections="50">
    <!--     <dubbo:parameter key="tps" value="5" />
        <dubbo:parameter key="tps.interval" value="1000" /> -->
    </dubbo:service>
<bean id="m00001.app001.xx.helloService" class="com.code260.ss.dubbo.demov.server.service.impl.HelloServiceImpl"/>

我们通过dubbo:service引用了一个HelloServiceImpl的bean,这样HelloServiceImpl对应的HelloService接口就算有一个provider了,那么dubbo:service是如何实现的?

先描述下整体流程:

graph TD
A[自定义spring配置标签-格式结构-]-->B[DubboNamespaceHandler对接spring自定义namespace注册标签解析器]
B-->C[定义DubboBeanDefinitionParser解析处理那些标签]
C-->D[ServiceBean对接spring的onApplicationEvent的ContextRefreshedEvent事件]
D-->E[ServiceBean export]

涉及DubboNamespaceHandler的部分在上一篇文章中已经解释了,此处跳过。

DubboBeanDefinitionParser

对接ServiceBean部分的代码:

else 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"));
            }
        }

className如果存在,则做这一段逻辑处理,如果className不存在则没有逻辑处理。

我们如果不配置class属性时,则会配置一个ref属性指向一个配置好的beanId。

如果className存在是指dubbo:service标签配置了class属性,此时自动生成ref属性。ref指向一个自动构建的bean定义。构建逻辑时候:构建RootBeanDefinition实例,从而构建BeanDefinitionHolder,最终把BeanDefinitionHolder实例放到原来beanDefinition的property中,property的名称是ref。

ServiceBean

该类实现了spring的ApplicationListener接口的onApplicationEvent方法,在该方法中在侦测到ContextRefreshedEvent事件时对接ServiceBean的export逻辑。详细的export逻辑会在后面文章中讲解。

afterPropertiesSet

阅读ServiceBean的afterPropertiesSet方法的代码发现,有不少代码,是干什么的呢?

主要是做了一些关联配置的设置处理,包括ProviderConfig、ApplicationConfig、ModuleConfig、RegistryConfig列表、MonitorConfig、ProtocolConfig列表等

destory

ServiceBean实现了DisposableBean接口,实现了其destory方法,用于在销毁时触发unexport逻辑。