dubbo可扩展的点的类的对象创建 都是用类似javaspi和javasist的思想来做的。所以看后面代码 先熟悉一下java的SPI和javasist的使用

如ServicesConfig的代码

private static final Protocol protocol = (Protocol)ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();

JAVASPI的作用

服务(接口实现类)的自动发现。我们定义好一组接口标准。而具体实现调用者根据自身需求自己实现

JavaSPI简单使用

我们模拟我们做了一个框架(jar)  框架的正常运行需要相关配置。配置加载方式由使用者来实现

1.定义接口

/**
 * 加载配置文件的句柄
 */
public interface LoadConfigHandle {
    public String  load();
}

2.定义实现类

public class HttpLoadConfigHandle implements LoadConfigHandle {
    public String load() {
        System.out.println("正在用http请求加载配置文件数据");
        return "";
    }
}
public class XmlLoadConfigHandle implements LoadConfigHandle {
    public String load() {
        System.out.println("正在加载配置文件xml");
        return "";
    }
}

在resource创建META-INF文件夹,再创建一个与接口全名称同名的文件。将实现类配置进去

com.liqiang.spi.XmlLoadConfigHandle
com.liqiang.spi.HttpLoadConfigHandle

3测试

public static void main(String[] str) throws InterruptedException {
        ServiceLoader<LoadConfigHandle> serviceLoader = ServiceLoader.load(LoadConfigHandle.class);
        Iterator<LoadConfigHandle> iterator = serviceLoader.iterator();
        while (iterator.hasNext()) {//next时候查缓存有没有加载过。如果没有加载才去加载
            LoadConfigHandle loadConfigHandle = iterator.next();//next时候查缓存有没有加载过。如果没有加载采取加载
loadConfigHandle.load(); } }

javasist使用

假设我们在运行时要动态的创建和编译类这样一个类

package com.liqiang.ssist;

public class Person {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Person(String name, int age){
         this.name=name;
         this.age=age;
    }
    public void  show(String ... date){
        System.out.println(this.name+"|"+this.age);
    }
}
  public static  void  main(String[]str) throws Exception{
        //ClassPool:CtClass对象的容器
        ClassPool pool = ClassPool.getDefault();
        //通过ClassPool生成一个public新类Emp.java
        CtClass ctClass = pool.makeClass("com.liqiang.ssist.Person");
        /**
         * 创建字段
         */
        //创建字段private String name;
        CtField  nameField = new CtField(pool.getCtClass("java.lang.String"),"name",ctClass);
        nameField.setModifiers(Modifier.PRIVATE);//私有字段
        ctClass.addField(nameField);
        //创建字段private int age;
        CtField  ageField = new CtField(pool.getCtClass("java.lang.Integer"),"age",ctClass);
        ageField.setModifiers(Modifier.PRIVATE);//私有字段
        ctClass.addField(ageField);
        /**
         * 为他们添加添加get set个访问器
         */
        ctClass.addMethod(CtNewMethod.getter("getName", nameField));
        ctClass.addMethod(CtNewMethod.setter("setName", nameField));
        ctClass.addMethod(CtNewMethod.getter("getAge", ageField));
        ctClass.addMethod(CtNewMethod.setter("setAge", ageField));
        /**
         * 添加构造函数
         */
        CtConstructor ctConstructor = new CtConstructor(new CtClass[]{pool.getCtClass("java.lang.String"),
                pool.getCtClass("java.lang.Integer")}, ctClass);
        //为构造函数设置函数体$1表示第一个参数 $2表示第二个参数
        StringBuffer buffer = new StringBuffer();
        buffer.append("{\n")
                .append("name=$1;\n")
                .append("age=$2;\n}");
        ctConstructor.setBody(buffer.toString());
        //把构造函数添加到新的类中
        ctClass.addConstructor(ctConstructor);
        /**
         * 定义方法
         */
        CtMethod ctMethod = new CtMethod(CtClass.voidType,"show",new CtClass[]{},ctClass);
        //为自定义方法设置修饰符
        ctMethod.setModifiers(Modifier.PUBLIC);
        //为自定义方法设置函数体
        StringBuffer buffer2 = new StringBuffer();
        buffer2.append("{\nSystem.out.println(this.name+\"|\"+this.age);\n")
                .append("}");
        ctMethod.setBody(buffer2.toString());
        ctClass.addMethod(ctMethod);
        /**
         * 反射生成实体
         */
        Class<?> clazz = ctClass.toClass();
        Constructor cla = clazz.getDeclaredConstructor(String.class,Integer.class);//获取构造函数的构造器

        Object obj=cla.newInstance("小明",12);//调用构造器生成对象
        obj.getClass().getMethod("show", new Class[]{}).invoke(obj, new Object[]{});
    }

输出

还有更多的使用方法 动态继承实现类。动态改变类方法 增加方法等。

dubbo-源码阅读之javaspi&javasist简单使用的更多相关文章

  1. 【Dubbo源码阅读系列】之远程服务调用(上)

    今天打算来讲一讲 Dubbo 服务远程调用.笔者在开始看 Dubbo 远程服务相关源码的时候,看的有点迷糊.后来慢慢明白 Dubbo 远程服务的调用的本质就是动态代理模式的一种实现.本地消费者无须知道 ...

  2. 【Dubbo源码阅读系列】服务暴露之远程暴露

    引言 什么叫 远程暴露 ?试着想象着这么一种场景:假设我们新增了一台服务器 A,专门用于发送短信提示给指定用户.那么问题来了,我们的 Message 服务上线之后,应该如何告知调用方服务器,服务器 A ...

  3. 【Dubbo源码阅读系列】服务暴露之本地暴露

    在上一篇文章中我们介绍 Dubbo 自定义标签解析相关内容,其中我们自定义的 XML 标签 <dubbo:service /> 会被解析为 ServiceBean 对象(传送门:Dubbo ...

  4. 【Dubbo源码阅读系列】之 Dubbo SPI 机制

    最近抽空开始了 Dubbo 源码的阅读之旅,希望可以通过写文章的方式记录和分享自己对 Dubbo 的理解.如果在本文出现一些纰漏或者错误之处,也希望大家不吝指出. Dubbo SPI 介绍 Java ...

  5. Dubbo源码阅读顺序

    转载: https://blog.csdn.net/heroqiang/article/details/85340958 Dubbo源码解析之配置解析篇,主要内容是<dubbo:service/ ...

  6. Dubbo源码阅读-服务导出

    Dubbo服务导出过程始于Spring容器发布刷新事件,Dubbo在接收到事件后,会立即执行服务导出逻辑.整个逻辑大致可分为三个部分,第一部分是前置工作,主要用于检查参数,组装URL.第二部分是导出服 ...

  7. dubbo源码阅读之SPI

    dubbo SPI SPI,全程Service Provider interface, java中的一种借口扩展机制,将借口的实现类注明在配置文件中,程序在运行时通过扫描这些配置文件从而获取全部的实现 ...

  8. dubbo源码阅读之自适应扩展

    自适应扩展机制 刚开始看代码,其实并不能很好地理解dubbo的自适应扩展机制的作用,我们不妨先把代码的主要逻辑过一遍,梳理一下,在了解了代码细节之后,回过头再来思考自适应扩展的作用,dubbo为什么要 ...

  9. 【Dubbo源码阅读系列】之 Dubbo XML 配置加载

    今天我们来谈谈 Dubbo XML 配置相关内容.关于这部分内容我打算分为以下几个部分进行介绍: Dubbo XML Spring 自定义 XML 标签解析 Dubbo 自定义 XML 标签解析 Du ...

随机推荐

  1. Codeforces Round #330 (Div. 2) D. Max and Bike 二分

    D. Max and Bike For months Maxim has been coming to work on his favorite bicycle. And quite recently ...

  2. 摄像头ov2685中关于sensor id 设置的相关的寄存器地址【转】

    本文转载自:http://blog.csdn.net/morixinguan/article/details/51220992 OV2685 : CHIP_ID address : 0x300A   ...

  3. Getting Installation aborted (Status 7) ApplyParsePerms: lsetfilecon of /syst...【转】

    OTA升级失败:原文http://en.miui.com/thread-112197-1-1.html Do you get this "Status 7" error in Re ...

  4. What is the difference between task and thread?

    http://stackoverflow.com/questions/4130194/what-is-the-difference-between-task-and-thread 回答一: A tas ...

  5. Android WiFi开发教程(二)——WiFi的搜索和连接

    在上一篇中我们介绍了WiFi热点的创建和关闭,如果你还没阅读过,建议先阅读上一篇文章Android WiFi开发教程(一)——WiFi热点的创建与关闭. 本章节主要继续介绍WiFi的搜索和连接. Wi ...

  6. 查看tensorflow pb模型文件的节点信息

    查看tensorflow pb模型文件的节点信息: import tensorflow as tf with tf.Session() as sess: with open('./quantized_ ...

  7. poj3041——最小点覆盖

    Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N g ...

  8. PCB 后台自动系统集成与邮件推送实现

    在PCB行业中,工程系统是主要数据生产者,而这些数据不仅仅给自己系统使用呀,我们需要将数据传递到各系统,才达到各系统共同协作的目的. 这里以问答方式对实现方式进行讲解.呵呵呵! 后台自动集成问题解答: ...

  9. PCB 3D PCB 后续改进与扩展功能一些想法

    再次感受到WelGl实现3D效果的震撼, 一.目前功能: Gerber与钻孔 解析 并转为3D实景图,用户360度操控 二.后续改进扩展功能: 1.增加ODB++解析 2. 3D 尺寸标注(外形尺寸, ...

  10. jquery.validate验证text,checkbox,radio,selected

    index.cshtml <form id="formLogin" method="post"> <div> <label for ...