dubbo源码阅读-配置(四)之javaSPI和javasis使用demo

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("{
")
                .append("name=$1;
")
                .append("age=$2;
}");
        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("{
System.out.println(this.name+"|"+this.age);
")
                .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[]{});
    }

输出

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

原文地址:https://www.cnblogs.com/LQBlog/p/12449357.html