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接口html

(3)實現ApplicationContextAware接口: 
實現這個接口須要覆蓋setApplicationContext(ApplicationContext applicationContext)方法。 
做用:能夠獲取ApplicationContext,咱們知道,Spring中最重要的就是ApplicationContext了,設置完ApplicationContext後就能夠隨意使用容器中的bean或者其餘的對象了。java

(4)實現ApplicationListener接口: 
實現這個接口須要覆蓋onApplicationEvent(ApplicationEvent event) 這個方法。 做用以下:spring

能夠監聽到所用經過applicationContext.publistEvent(ApplicationEvent event))發佈的事件,Spring在啓動過程當中,對象初始化完成後,會調用publistEvent方法,發佈事件,隨後全部實現了ApplicationListener的接口均可以接收到事件並執行響應的操做。app

具體能夠參考: 
http://wiki.jikexueyuan.com/project/spring/event-handling-in-spring.html 
http://www.cnblogs.com/ArtsCrafts/p/Spring_Event.htmlide

此處是經過監聽Spring的內置事件ContextRefreshedEvent調用export()方法暴露服務。ui

(5)實現BeanNameAware接口: 
實現這個接口須要覆蓋setBeanName(String name) 方法做用:讓Bean獲取本身在BeanFactory配置中的名字(根據狀況是id或者name),適用於某個bean須要訪問配置文件中自身bean的id屬性的狀況。spa

    也就是說在作service標籤解析的時候,須要定義的beanName,這個獲取到的beanName用在了afterPropertiesSet方法在setPath裏面。 
具體參考: 
http://langgufu.iteye.com/blog/1499966 
http://www.cnblogs.com/liunanjava/p/4401089.html.net

說明: 
經過運行dubbo-demo-provider發現,此處給出的beanName是:com.alibaba.dubbo.demo.DemoService。理論上來說應該是設置的id纔對,那麼咱們看配置文件:code

<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是如何設置進去的呢?xml

查看解析代碼咱們能夠看到這樣的一段:

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

相關文章
相關標籤/搜索