幾個(gè)重要的類(lèi)
-
DubboNamespaceHandler
窒百。該類(lèi)繼承NamespaceHandlerSupport
寨昙,即通過(guò)spring對(duì)擴(kuò)展標(biāo)簽的支持僻肖,對(duì)dubbo自定義的標(biāo)簽進(jìn)行解析,在解析時(shí)會(huì)注冊(cè)DubboBootstrapApplicationListener
缅叠。 -
DubboBootstrapApplicationListener
悄泥。該類(lèi)實(shí)現(xiàn)了ApplicationListener
和ApplicationContextAware
,注入ApplicatonContext
并且監(jiān)聽(tīng)ApplicationContext
的onContextRefreshedEvent
和onContextClosedEvent
事件肤粱,在onContextRefresh
時(shí)調(diào)用DubboBootstrap.start();
開(kāi)啟dubbo弹囚。 -
DubboBootstrap
。dubbo
的啟動(dòng)類(lèi)狼犯,start
方法中調(diào)用export
方法進(jìn)行服務(wù)提供端的服務(wù)暴露余寥,內(nèi)部會(huì)調(diào)用ServiceConfig
的export
來(lái)暴露服務(wù)。 -
ServiceConfig
悯森,主要是對(duì)提供者方法的暴露宋舷,主要邏輯在doExport
方法內(nèi)。默認(rèn)是先將ServiceImpl包裝成一個(gè)代理對(duì)象AbstractProxyInvoker
瓢姻,該過(guò)程是通過(guò)某個(gè)代理工廠來(lái)操作的祝蝠,例如JdkProxyFactory
或者JavassistProxyFactory
,默認(rèn)是后者。包裝完成后交給某個(gè)協(xié)議實(shí)現(xiàn)類(lèi)來(lái)將Invoker
轉(zhuǎn)換為Exporter
绎狭,默認(rèn)為DubboProtocol
细溅。 -
DubboProtocol
。該類(lèi)繼承了AbstractProtocol
儡嘶,間接實(shí)現(xiàn)了Protocol
喇聊。在export
方法中調(diào)用HeaderExchanger
的bind
方法,進(jìn)而調(diào)用transport
的bind
來(lái)開(kāi)啟server蹦狂。該處定義了很多Transport誓篱,默認(rèn)的是使用netty,并且是netty4凯楔,即在NettyTransporter
中開(kāi)啟netty server窜骄,在netty中添加了dubbo協(xié)議解析的部分,主要是使用了DubboCountCodec
摆屯,內(nèi)部調(diào)用DubboCodec
進(jìn)行解析邻遏。開(kāi)啟server時(shí)注冊(cè)一個(gè)ChannelHandlerAdapter
,通過(guò)該ChannelHandler處理Channel并找到Invocation
對(duì)應(yīng)的Exporter
虐骑,再通過(guò)Exporter
來(lái)找到Invoker
准验,這里的Invoker
就是上面ServiceImp
生成的代理類(lèi)。 -
DubboCodec
富弦。dubbo協(xié)議的詳細(xì)代碼沟娱。 -
ServiceClassPostProcessor
。該類(lèi)實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor
腕柜,將上面的DubboBootstrapApplicationListener
注冊(cè)為spring
中的bean
济似。該類(lèi)中還添加了對(duì)注解的支持,添加掃描包路徑可以自動(dòng)注冊(cè)要暴露的service
類(lèi)盏缤。
dubbo遵循"微內(nèi)核+插件"的設(shè)計(jì)模式砰蠢,大部分插件都使用了spi的方式。
大多數(shù)會(huì)使用xml的方式使用dubbo唉铜,這時(shí)候是通過(guò)DubboNamespaceHandler
來(lái)對(duì)DubboBootstrapApplicationListener
進(jìn)行bean的注冊(cè)台舱。如果不使用xml,而是通過(guò)JavaConfig的方式潭流,可以手動(dòng)注冊(cè)ServiceClassPostProcessor
作為bean竞惋,如下所示
provider
@Configuration
public class CustomDubboConfig {
@Bean
public ServiceClassPostProcessor serviceClassPostProcessor(){
return new ServiceClassPostProcessor("com.dubbo.provider.service.impl");
}
@Bean
public ApplicationConfig applicationConfig(){
ApplicationConfig config = new ApplicationConfig("without-xml-provide");// 要掃描的service包
return config;
}
@Bean
public RegistryConfig registryConfig(){
return new RegistryConfig("zookeeper://127.0.0.1:2181");
}
}
Service
通過(guò)注解DubboService
進(jìn)行暴露。
@DubboService
public class DemoServiceImpl implements DemoService {
public String sayHello(String s) {
return "from provider:" + s;
}
}
consumer
配置類(lèi)
@Configuration
public class CustomDubboConfig {
@Bean
public ServiceClassPostProcessor serviceClassPostProcessor(){
return new ServiceClassPostProcessor();
}
@Bean
public ApplicationConfig applicationConfig(){
ApplicationConfig config = new ApplicationConfig("without-xml-consumer");
return config;
}
@Bean
public RegistryConfig registryConfig(){
return new RegistryConfig("zookeeper://127.0.0.1:2181");
}
@Bean
public ConsumerService consumerService(){
return new ConsumerService((DemoService) referenceConfigs().get(DemoService.class).get());
}
@Bean
public Map<Class,ReferenceConfig> referenceConfigs(){
ReferenceConfig<DemoService> config = new ReferenceConfig<>();
config.setInterface(DemoService.class);
Map<Class,ReferenceConfig> map = new HashMap<>();
map.put(DemoService.class, config);
return map;
}
}
消費(fèi)者端的service類(lèi)
public class ConsumerService {
DemoService demoService;
public ConsumerService(DemoService service){
demoService = service;
}
public String hello(){
String result = demoService.sayHello("ace");
return result;
}
}
測(cè)試成功
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(CustomDubboConfig.class);
context.start();
ConsumerService service = context.getBean(ConsumerService.class);
System.out.println(service.hello());
System.in.read();
也可以使用DubboReference
為方法或者屬性添加注解灰嫉,如下所示
public class ConsumerService {
@DubboReference(interfaceClass = DemoService.class)
DemoService demoService;
public String hello(){
String result = demoService.sayHello("ace");
return result;
}
}
這時(shí)候需要在配置類(lèi)文件開(kāi)啟Dubbo配置
@Configuration
@EnableDubboConfig
public class CustomDubboConfig {
...
需要注意的是拆宛,當(dāng)前使用的是apache.dubbo
,而不是alibaba.dubbo
讼撒,需要高版本的spring
浑厚,還要添加org.apache.curator
的依賴股耽。curator
是一個(gè)zookeeper client實(shí)現(xiàn)。
參考