美文网首页
dubbo源码 start

dubbo源码 start

作者: Ace_b90f | 来源:发表于2020-07-09 16:48 被阅读0次

    几个重要的类

    • DubboNamespaceHandler。该类继承NamespaceHandlerSupport,即通过spring对扩展标签的支持,对dubbo自定义的标签进行解析,在解析时会注册DubboBootstrapApplicationListener
    • DubboBootstrapApplicationListener。该类实现了ApplicationListenerApplicationContextAware,注入ApplicatonContext并且监听ApplicationContextonContextRefreshedEventonContextClosedEvent事件,在onContextRefresh时调用DubboBootstrap.start();开启dubbo。
    • DubboBootstrapdubbo的启动类,start方法中调用export方法进行服务提供端的服务暴露,内部会调用ServiceConfigexport来暴露服务。
    • ServiceConfig,主要是对提供者方法的暴露,主要逻辑在doExport方法内。默认是先将ServiceImpl包装成一个代理对象AbstractProxyInvoker,该过程是通过某个代理工厂来操作的,例如JdkProxyFactory或者JavassistProxyFactory,默认是后者。包装完成后交给某个协议实现类来将Invoker转换为Exporter,默认为DubboProtocol
    • DubboProtocol。该类继承了AbstractProtocol,间接实现了Protocol。在export方法中调用HeaderExchangerbind方法,进而调用transportbind 来开启server。该处定义了很多Transport,默认的是使用netty,并且是netty4,即在NettyTransporter中开启netty server,在netty中添加了dubbo协议解析的部分,主要是使用了DubboCountCodec,内部调用DubboCodec进行解析。开启server时注册一个ChannelHandlerAdapter,通过该ChannelHandler处理Channel并找到Invocation对应的Exporter,再通过Exporter来找到Invoker,这里的Invoker就是上面ServiceImp生成的代理类。
    • DubboCodec。dubbo协议的详细代码。
    • ServiceClassPostProcessor。该类实现BeanDefinitionRegistryPostProcessor,将上面的DubboBootstrapApplicationListener注册为spring中的bean。该类中还添加了对注解的支持,添加扫描包路径可以自动注册要暴露的service类。

    dubbo遵循"微内核+插件"的设计模式,大部分插件都使用了spi的方式。

    大多数会使用xml的方式使用dubbo,这时候是通过DubboNamespaceHandler来对DubboBootstrapApplicationListener进行bean的注册。如果不使用xml,而是通过JavaConfig的方式,可以手动注册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通过注解DubboService进行暴露。

    @DubboService
    public class DemoServiceImpl implements DemoService {
        public String sayHello(String s) {
            return "from provider:" + s;
        }
    }
    
    consumer

    配置类

    @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;
        }
    }
    
    

    消费者端的service类

    public class ConsumerService {
        DemoService demoService;
        public ConsumerService(DemoService service){
            demoService = service;
        }
    
        public String hello(){
            String result = demoService.sayHello("ace");
            return result;
        }
    }
    

    测试成功

            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;
        }
    }
    

    这时候需要在配置类文件开启Dubbo配置

    @Configuration
    @EnableDubboConfig
    public class CustomDubboConfig {
      ...
    

    需要注意的是,当前使用的是apache.dubbo,而不是alibaba.dubbo,需要高版本的spring,还要添加org.apache.curator的依赖。curator是一个zookeeper client实现。

    参考

    相关文章

      网友评论

          本文标题:dubbo源码 start

          本文链接:https://www.haomeiwen.com/subject/gzescktx.html