Dubbo的ServiceBean机制分析

ServiceBean分析

ServiceBean< T>这个类 
(1) 继承了ServiceConfig< T>:这个类主要封装标签的属性,如ref,path,methods等; 
(2)实现InitializingBean, DisposableBean接口,其作用如下:关于在spring 容器初始化 bean 和销毁前所做的操作定义方式有三种: 
第一种:通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作 
第二种是:通过 在xml中定义init-method 和 destory-method方法 
第三种是: 通过bean实现InitializingBean和 DisposableBean接口

(3)实现ApplicationContextAware接口: 
实现这个接口需要覆盖setApplicationContext(ApplicationContext applicationContext)方法。 
作用:可以获取ApplicationContext,我们知道,Spring中最重要的就是ApplicationContext了,设置完ApplicationContext后就可以随意使用容器中的bean或者其他的对象了。

(4)实现ApplicationListener接口: 
实现这个接口需要覆盖onApplicationEvent(ApplicationEvent event) 这个方法。 作用如下:

可以监听到所用通过applicationContext.publistEvent(ApplicationEvent event))发布的事件,Spring在启动过程中,对象初始化完成后,会调用publistEvent方法,发布事件,随后所有实现了ApplicationListener的接口都可以接收到事件并执行响应的操作。

具体可以参考: 
http://wiki.jikexueyuan.com/project/spring/event-handling-in-spring.html 
http://www.cnblogs.com/ArtsCrafts/p/Spring_Event.html

此处是通过监听Spring的内置事件ContextRefreshedEvent调用export()方法暴露服务。

(5)实现BeanNameAware接口: 
实现这个接口需要覆盖setBeanName(String name) 方法作用:让Bean获取自己在BeanFactory配置中的名字(根据情况是id或者name),适用于某个bean需要访问配置文件中自身bean的id属性的情况。

    也就是说在做service标签解析的时候,需要定义的beanName,这个获取到的beanName用在了afterPropertiesSet方法在setPath里面。 
具体参考: 
http://langgufu.iteye.com/blog/1499966 
http://www.cnblogs.com/liunanjava/p/4401089.html

说明: 
通过运行dubbo-demo-provider发现,此处给出的beanName是:com.alibaba.dubbo.demo.DemoService。理论上来讲应该是设置的id才对,那么我们看配置文件:

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

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

    我们发现这里并没有为< dubbo:service>这个标签指定id或者name属性,那么这个beanName是如何设置进去的呢?

查看解析代码我们可以看到这样的一段:

String id = element.getAttribute("id");
        if ((id == null || id.length() == 0) && required) {
            String generatedBeanName = element.getAttribute("name");
            if (generatedBeanName == null || generatedBeanName.length() == 0) {
                if (ProtocolConfig.class.equals(beanClass)) {
                    generatedBeanName = "dubbo";
                } else {
                    generatedBeanName = element.getAttribute("interface");
                }
            }
            if (generatedBeanName == null || generatedBeanName.length() == 0) {
                generatedBeanName = beanClass.getName();
            }
            id = generatedBeanName; 
            int counter = 2;
            while(parserContext.getRegistry().containsBeanDefinition(id)) {
                id = generatedBeanName + (counter ++);
            }
        }
        if (id != null && id.length() > 0) {
            if (parserContext.getRegistry().containsBeanDefinition(id))  {
                throw new IllegalStateException("Duplicate spring bean id " + id);
            }
            parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
            beanDefinition.getPropertyValues().addPropertyValue("id", id);
        }
        ...

    到这里就很清楚了,原因是如果没有设置id属性的话,会取interface属性作为SpringBean的id。

其他的内容就是一些设置providerConfig,applicationConfig,moduleConfig,registryConfigs,monitorConfig,protocolConfigs

具体可以参考: 
http://chenjingbo.iteye.com/blog/2008325

参考文献:http://blog.csdn.net/xiaoxiaoxuanao/article/details/54691641

猜你喜欢

转载自my.oschina.net/u/3729778/blog/1626508