热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

利用Dubbo的SPI扩展容器

在实际开发中,很多Dubbo的服务提供者都会运行在web容器上,如果提供者服务上同时对外

在实际开发中,很多Dubbo的服务提供者都会运行在web容器上,如果提供者服务上同时对外提供http服务的话,这么做是有必要的,但如果你的服务提供者只是对外提供dubbo服务的话,那么用web容器就有些重了,因为毕竟web容器主要是用来响应http请求以及静态页面的。如果单独作为dubbo服务提供者,只需要通过一个main方法加载一个简单的spring容器将服务暴露出去即可。
注:本文以dubbo的2.6.5版本为例
  • 一、Dubbo的内置容器

dubbo内置了三种容器
Log4jContainer:只是针对log4j配置文件做了处理。

LogbackContainer:只是针对logback日志配置文件做了处理。

SpringContainer:
它的start方法会创建ClassPathXmlApplicationContext容器,然后分别执行refresh方法和start方法刷,暴露dubbo服务;其stop方法会执行ClassPathXmlApplicationContext的stop及close方法。

可以看到,这三种容器,只有SpringContainer真正的加载了容器并暴露了服务,所以要用dubbo自带的容器的话,SpringContainer是必选的,可以单独使用,另外两个需要配合SpringContainer使用,但是如果要使用SpringContainer的话,你需要把配置文件放到指定的为止,因为源码中已经定义死了:

所以我们用的时候一般是通过实现Container接口来自定义一个容器,然后重写Main类通过Dubbo的SPI机制加载自定义的容器,这样可以自定义加载配置文件。
  • 二、自定义Container

  • 2.1、首先用idea新建一个基于maven的java项目,添加dubbo,zk等依赖,具体的项目创建过程略过。

  • 2.2、写一个接口和实现类,用来对外暴露

  • 2.3、添加spring配置文件,dubbo配置文件等

  • 2.4、定义一个容器类,实现Container接口

    package com.ayo;


    import com.alibaba.dubbo.container.Container;
    import com.ayo.util.PathUtil;
    import org.springframework.context.support.FileSystemXmlApplicationContext;


    /**
    * 自定义一个容器
    */
    public class CustomContainer implements Container{


    /**
    * spring容器上下文
    */
    static FileSystemXmlApplicationContext context;


    /**
    * 启动容器
    */
    public void start() {
    try {
    String path = PathUtil.getAppConfPath().concat(PathUtil.sp()).concat("spring.xml");
    cOntext= new FileSystemXmlApplicationContext(path);
    }catch (Exception e){
    e.printStackTrace();
    }
    }


    /**
    * 停止容器
    */
    public void stop() {
    try {
    if (context != null){
    context.stop();
    context.close();
    cOntext= null;
    }
    }catch (Exception e){
    e.printStackTrace();
    }
    }
    }

    • 2.5、在resources下建一个文件夹命名为META-INF,然后在META-INF下再建一个文件夹命名为dubbo,然后建立一个文件命名为com.alibaba.dubbo.container.Container,里面写上内容

    为什么要这么做?这就是Dubbo的SPI,不知道的可以看下,传送门:

    Dubbo的SPI、适配器原理、动态编译原理

    • 2.6、写一个Main类用于加载和启动自定义的Container

      package com.ayo;


      import com.alibaba.dubbo.common.extension.ExtensionLoader;
      import com.alibaba.dubbo.container.Container;
      import java.text.SimpleDateFormat;
      import java.util.Date;




      /**
      * 自定义dubbo容器
      *
      * @author ayo
      */
      public class Main {


      /**
      * dubbo优雅关机
      */
      public static final String SHUTDOWN_HOOK_KEY = "dubbo.shutdown.hook";


      private static volatile boolean running = true;


      public static void main(String[] args) {
      try {
      final Container customCOntainer= ExtensionLoader.getExtensionLoader(Container.class).getExtension("custom");
      //在dubbo优雅关机的时候会触发此钩子函数
      if ("true".equals(System.getProperty(SHUTDOWN_HOOK_KEY))) {
      Runtime.getRuntime().addShutdownHook(new Thread() {
      public void run() {
      try {
      customContainer.stop();
      System.out.println("Dubbo " + customContainer.getClass().getSimpleName() + " stopped!");
      } catch (Throwable t) {
      t.printStackTrace();
      }
      synchronized (Main.class) {
      running = false;
      Main.class.notify();
      }
      }
      });
      }
      customContainer.start();
      System.out.println("Dubbo " + customContainer.getClass().getSimpleName() + " started!");
      System.out.println(new SimpleDateFormat("[yyyy-MM-dd HH:mm:ss]").format(new Date()) + " Dubbo service server started!");
      } catch (RuntimeException e) {
      e.printStackTrace();
      System.exit(1);
      }
      synchronized (Main.class) {
      while (running) {
      try {
      Main.class.wait();
      } catch (Throwable e) {
      }
      }
      }
      }
      }

      • 2.7、运行Main类中的main方法

      • 2.8、看下服务有没有注册到zk

      • 2.9、写个dubbo消费者测试下接口是否正常

        package com.ayo;


        import com.alibaba.dubbo.config.ApplicationConfig;
        import com.alibaba.dubbo.config.ReferenceConfig;
        import com.alibaba.dubbo.config.RegistryConfig;
        import com.ayo.service.UserService;


        public class Consumer {


        public static void main(String[] args) {
        1.创建服务引用对象实例
        ReferenceConfig referenceCOnfig= new ReferenceConfig();


        2.设置应用程序信息
        ApplicationConfig applicatiOnConfig= new ApplicationConfig("dubbo-consumer");
        referenceConfig.setApplication(applicationConfig);


        //3.设置服务注册中心
        RegistryConfig registryCOnfig= new RegistryConfig("zookeeper://192.168.209.129:2181");
        referenceConfig.setRegistry(registryConfig);


        //3.设置服务接口和超时时间
        referenceConfig.setInterface(UserService.class);
        referenceConfig.setTimeout(5000);


        //5.引用服务
        UserService userService = referenceConfig.get();


        //6.调用服务
        System.out.println(userService.getUserName());
        }
        }

        需要demo的私我。


        推荐阅读
        • 深入解析 Apache Shiro 安全框架架构
          本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
        • 将Web服务部署到Tomcat
          本文介绍了如何在JDeveloper 12c中创建一个Java项目,并将其打包为Web服务,然后部署到Tomcat服务器。内容涵盖从项目创建、编写Web服务代码、配置相关XML文件到最终的本地部署和验证。 ... [详细]
        • 实体映射最强工具类:MapStruct真香 ... [详细]
        • Explore how Matterverse is redefining the metaverse experience, creating immersive and meaningful virtual environments that foster genuine connections and economic opportunities. ... [详细]
        • 本文详细介绍如何使用Python进行配置文件的读写操作,涵盖常见的配置文件格式(如INI、JSON、TOML和YAML),并提供具体的代码示例。 ... [详细]
        • 本文介绍了Java并发库中的阻塞队列(BlockingQueue)及其典型应用场景。通过具体实例,展示了如何利用LinkedBlockingQueue实现线程间高效、安全的数据传递,并结合线程池和原子类优化性能。 ... [详细]
        • 深入理解Cookie与Session会话管理
          本文详细介绍了如何通过HTTP响应和请求处理浏览器的Cookie信息,以及如何创建、设置和管理Cookie。同时探讨了会话跟踪技术中的Session机制,解释其原理及应用场景。 ... [详细]
        • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
        • MySQL 数据库迁移指南:从本地到远程及磁盘间迁移
          本文详细介绍了如何在不同场景下进行 MySQL 数据库的迁移,包括从一个硬盘迁移到另一个硬盘、从一台计算机迁移到另一台计算机,以及解决迁移过程中可能遇到的问题。 ... [详细]
        • Hadoop入门与核心组件详解
          本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
        • 本文探讨了领域驱动设计(DDD)的核心概念、应用场景及其实现方式,详细介绍了其在企业级软件开发中的优势和挑战。通过对比事务脚本与领域模型,展示了DDD如何提升系统的可维护性和扩展性。 ... [详细]
        • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
        • QUIC协议:快速UDP互联网连接
          QUIC(Quick UDP Internet Connections)是谷歌开发的一种旨在提高网络性能和安全性的传输层协议。它基于UDP,并结合了TLS级别的安全性,提供了更高效、更可靠的互联网通信方式。 ... [详细]
        • 深入了解 Windows 窗体中的 SplitContainer 控件
          SplitContainer 控件是 Windows 窗体中的一种复合控件,由两个可调整大小的面板和一个可移动的拆分条组成。本文将详细介绍其功能、属性以及如何通过编程方式创建复杂的用户界面。 ... [详细]
        • 作为一名专业的Web前端工程师,掌握HTML和CSS的命名规范是至关重要的。良好的命名习惯不仅有助于提高代码的可读性和维护性,还能促进团队协作。本文将详细介绍Web前端开发中常用的HTML和CSS命名规范,并提供实用的建议。 ... [详细]
        author-avatar
        手机用户2502941011
        这个家伙很懒,什么也没留下!
        PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
        Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有