真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

怎么用Dubbo與Spring整合解析配置文件

這篇文章主要介紹“怎么用Dubbo與Spring整合解析配置文件”,在日常操作中,相信很多人在怎么用Dubbo與Spring整合解析配置文件問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”怎么用Dubbo與Spring整合解析配置文件”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

站在用戶的角度思考問題,與客戶深入溝通,找到婺城網(wǎng)站設(shè)計(jì)與婺城網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、空間域名、虛擬空間、企業(yè)郵箱。業(yè)務(wù)覆蓋婺城地區(qū)。

1、Dubbo消費(fèi)者調(diào)用服務(wù)提供者例子

本專欄分析的Dubbo源碼是基于2.6.x版本

public class Consumer {

    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = 
		            new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-consumer.xml"});
        context.start();
        DemoService demoService = (DemoService) context.getBean("demoService");

        while (true) {
            try {
                Thread.sleep(1000);
                String hello = demoService.sayHello("world");
                System.out.println(hello); 
            } catch (Throwable throwable) {
                throwable.printStackTrace();
            }
        }
    }
}




    
    
    
public class Provider {

    public static void main(String[] args) throws Exception {
        System.setProperty("java.net.preferIPv4Stack", "true");
        ClassPathXmlApplicationContext context = 
                            new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-provider.xml"});
        context.start();
        System.in.read(); 
    }
}



    
    
    
    
    

2、Spring解析dubbo配置文件

??先啟動(dòng)服務(wù)提供者,再啟動(dòng)消費(fèi)者,發(fā)現(xiàn)控制臺(tái)可以正常輸出。下面分析一下Spring是如何解析dubbo的消費(fèi)者和服務(wù)提供者的配置文件。Spring容器提供了IOC功能,可以替我們生成bean。通常,我們將bean的定義放在xml文件中,我們來(lái)分析一下Spring加載xml配置文件并生成bean過(guò)程。Spring提供的容器分為兩種:BeanFactory和ApplicationContext。其中BeanFactory是懶加載,也就是延遲初始化,它在你調(diào)用getBean時(shí)才會(huì)初始化這個(gè)bean,而ApplicationContext是初始化容器時(shí)就會(huì)加載非延遲初始化的bean。先簡(jiǎn)單概況下Spring容器生成bean的過(guò)程,首先通過(guò)loadBeanDefinition過(guò)程將bean的信息封裝成一個(gè)個(gè)BeanDefinition,然后再根據(jù)這些BeanDefinition創(chuàng)建bean。下面看Spring解析Dubbo的配置文件并生成bean的過(guò)程。

// 1、new ClassPathXmlApplicationContext時(shí)Spring容器初始化,此時(shí)會(huì)先調(diào)用loadBeanDefinition方法去加載解析xml配置文件
context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-provider.xml"});
// 2、加載配置文件最終會(huì)走到這里
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
	if (delegate.isDefaultNamespace(root)) {
		NodeList nl = root.getChildNodes();
                // 3、這里其實(shí)已經(jīng)通過(guò)dom4j將xml文件解析成了Document,將xml中的一項(xiàng)一項(xiàng)配置解析成了一個(gè)個(gè)Node去讀取處理.
		for (int i = 0; i < nl.getLength(); i++) {
			Node node = nl.item(i);
			if (node instanceof Element) {
				Element ele = (Element) node;
                                // 4、判斷是否是Spring默認(rèn)可以處理的Node.這里看下面截圖,由于dubbo:application,
                                // 是dubbo中定義的,不屬于Spring的命名空間管理
				if (delegate.isDefaultNamespace(ele)) {
					parseDefaultElement(ele, delegate);
				}
				else {
					delegate.parseCustomElement(ele);
				}
			}
		}
	}
}

怎么用Dubbo與Spring整合解析配置文件

public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {
        // http://dubbo.apache.org/schema/dubbo
	String namespaceUri = getNamespaceURI(ele);
        // DubboNameSpaceHandler
        NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
	if (handler == null) {
		return null;
	}
	return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
private static BeanDefinition parse(Element element, ParserContext parserContext, 
                                                                           Class beanClass, boolean required) {
        RootBeanDefinition beanDefinition = new RootBeanDefinition();
        // class com.alibaba.dubbo.config.ApplicationConfig
        beanDefinition.setBeanClass(beanClass);
        beanDefinition.setLazyInit(false);
        // 解析id屬性
        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);
            }
            // 注冊(cè)BeanDefinition
            parserContext.getRegistry().registerBeanDefinition(id, beanDefinition);
            // 將id屬性放入beanDefinition中,后續(xù)getBean創(chuàng)建bean時(shí)就是根據(jù)這些屬性來(lái)創(chuàng)建bean,
            // 這里創(chuàng)建的bean是ApplicationConfig
            beanDefinition.getPropertyValues().addPropertyValue("id", id);
        }

        // 刪去一些代碼,reference是解析得到的value值,可見這里將屬性和屬性值都放入了BeanDefinition
        beanDefinition.getPropertyValues().addPropertyValue(property, reference);
        return beanDefinition;
}

到這里就解析完了,Spring將xml中的application節(jié)點(diǎn)解析成一個(gè)BeanDefinition,并注冊(cè)到Registry中,Registry就是一個(gè)Map。下面分析Spring創(chuàng)建這個(gè)ApplicationConfig的過(guò)程。

3、Spring創(chuàng)建ApplicationConfig

context = new ClassPathXmlApplicationContext(new String[]{"META-INF/spring/dubbo-demo-provider.xml"});
// Spring容器的初始化過(guò)程,new ClassPathXmlApplicationContext后會(huì)走到這里
public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		prepareRefresh();
		// 這里面就會(huì)執(zhí)行上面的分析過(guò)程,調(diào)用loadBeanDefinition解析BeanDefinition
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
		prepareBeanFactory(beanFactory);
		try {
			postProcessBeanFactory(beanFactory);
			invokeBeanFactoryPostProcessors(beanFactory);
			registerBeanPostProcessors(beanFactory);
			initMessageSource();
			initApplicationEventMulticaster();
			onRefresh();
			registerListeners();
			// Instantiate all remaining (non-lazy-init) singletons.可以看到Spring容器初始化
			// 的后面會(huì)初始化非延遲加載的bean,這里會(huì)走到下圖的preInstantiasteSingletons方法
			finishBeanFactoryInitialization(beanFactory);
			finishRefresh();
		}
	}
}

怎么用Dubbo與Spring整合解析配置文件

// Spring創(chuàng)建bean最終會(huì)走到這里
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, 
                                                     final Object[] args) throws BeanCreationException {
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
                // 刪除一些無(wú)用代碼,這里會(huì)調(diào)用反射創(chuàng)建bean,創(chuàng)建完僅是一個(gè)空的bean,屬性還沒有賦值
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);

	Object exposedObject = bean;
	try {
                // 屬性賦值,最終也是調(diào)用反射進(jìn)行賦值
		populateBean(beanName, mbd, instanceWrapper);
		if (exposedObject != null) {
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
	}
	return exposedObject;
}
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
        // 這里的pvs就是之前解析配置文件得到BeanDefinition時(shí),給BeanDefinition注入進(jìn)去的
	PropertyValues pvs = mbd.getPropertyValues();
        // 刪除一些代碼,最終這里會(huì)調(diào)用反射賦值,跳來(lái)跳去有點(diǎn)復(fù)雜
	applyPropertyValues(beanName, mbd, bw, pvs);
}
protected void addSingleton(String beanName, Object singletonObject) {
        // 最終創(chuàng)建完bean以后會(huì)將它保存起來(lái)(猜測(cè),Spring容器初始化以后,非懶加載的bean已經(jīng)以如下方式
        // 保存到Spring容器中了,后續(xù)通過(guò)@Autowired注解)來(lái)獲取時(shí)就是從這里面獲取,只是分析,還沒有看源碼)
	synchronized (this.singletonObjects) {
		this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
		this.singletonFactories.remove(beanName);
		this.earlySingletonObjects.remove(beanName);
		this.registeredSingletons.add(beanName);
	}
}

怎么用Dubbo與Spring整合解析配置文件

到此,關(guān)于“怎么用Dubbo與Spring整合解析配置文件”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!


分享名稱:怎么用Dubbo與Spring整合解析配置文件
路徑分享:http://weahome.cn/article/piejep.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部