Dubbo-Adaptive自适应加载机制

 javassist

Javassist是一款字节码编辑工具,可以直接编辑和生成Java生成的字节码,以达到对.class文件进行动态修改的效果。熟练使用这套工具,可以让Java编程更接近与动态语言编程。

maven依赖

         <dependency>
            <groupId>org.javassist</groupId>
            <artifactId>javassist</artifactId>
            <version>3.20.0-GA</version>
        </dependency>

API讲解

/**
 * Javassist测试类
 * @author yangyanping
 * @date 2021-07-28
 */
public class JavassistTest {
    public static void main(String[] args) throws Exception {
        //初始化 javassist 的类池
        ClassPool pool = ClassPool.getDefault();
        // 创建一个Hello 类
        CtClass ctClass = pool.makeClass("com.jd.Hello");

        // 添加一个ID属性
        CtField idField = new CtField(CtClass.longType, "id", ctClass);
        ctClass.addField(idField);

        // 添加一个test 方法
        CtMethod ctMethod = CtNewMethod.make("public static void test() {System.out.println(\"Hello World !\");}",ctClass);
        ctClass.addMethod(ctMethod);

        //生成类
        Class<?> clazz = ctClass.toClass();
        //创建实例
        Object obj = clazz.newInstance();

        Method method = clazz.getDeclaredMethod("test",null);
        method.invoke(obj,null);
    }
}

运行结果:

Hello World !

自适应加载机制 

为 Dubbo 更加灵活的使一个接口不通过硬编码加载扩展机制,而是通过使用过程中进行加载,Dubbo 的另一加载机制——自适应加载。
自适应加载机制使用 @Adaptive 标注:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Adaptive {
    String[] value() default {};
}

 @Adaptive 注解使用

/**
 * 水果 接口
 * @author yangyanping
 * @date 2021-07-30
 */
@SPI("apple")
public interface Fruit {
    @Adaptive("adaptiveTest")
    String echo(URL url);
}

 Apple 实现类

public class Apple implements Fruit {
    @Override
    public String echo(URL url) {
        return "Apple";
    }
}

Banlana 实现类 

public class Banlana implements Fruit {
    @Override
    public String echo(URL url) {
        return "banana";
    }
}

AdaptiveTest 单元测试类
public class AdaptiveTest {
    @Test
    public void testGenerator() {
        URL url = URL.valueOf("dubbo://localhost:8082?adaptiveTest=apple");
        String msg = ExtensionLoader.getExtensionLoader(Fruit.class).getAdaptiveExtension().echo(url);
        System.out.println(msg);
        
        url = URL.valueOf("dubbo://localhost:8082?adaptiveTest=banana");
        msg = ExtensionLoader.getExtensionLoader(Fruit.class).getAdaptiveExtension().echo(url);
        System.out.println(msg);

        url = URL.valueOf("dubbo://localhost:8082");
        msg = ExtensionLoader.getExtensionLoader(Fruit.class).getAdaptiveExtension().echo(url);
        System.out.println(msg);
    }
}

运行结果:

Apple
banana
Apple

Fruit$Adaptive 代理类 

package com.jd.dubbo.adaptive;

import com.alibaba.dubbo.common.extension.ExtensionLoader;

public class Fruit$Adaptive implements com.jd.dubbo.adaptive.Fruit {
    public java.lang.String echo(com.alibaba.dubbo.common.URL arg0) {
        if (arg0 == null) throw new IllegalArgumentException("url == null");
        
        com.alibaba.dubbo.common.URL url = arg0;
        String extName = url.getParameter("adaptiveTest", "apple");
        
        if (extName == null)
            throw new IllegalStateException("Fail to get extension(com.jd.dubbo.adaptive.Fruit) name from url(" + url.toString() + ") use keys([adaptiveTest])");
        
        com.jd.dubbo.adaptive.Fruit extension = (com.jd.dubbo.adaptive.Fruit) ExtensionLoader.getExtensionLoader(com.jd.dubbo.adaptive.Fruit.class).getExtension(extName);
        return extension.echo(arg0);
    }
}

 创建扩展到对象

private Class<?> createAdaptiveExtensionClass() {
        // 生成自适应扩展代码
        String code = new AdaptiveClassCodeGenerator(type, cachedDefaultName).generate();
        // 获取扩展类加载器
        ClassLoader classLoader = findClassLoader();
        // 获取编译器类型的实现类
        org.apache.dubbo.common.compiler.Compiler compiler = ExtensionLoader.getExtensionLoader(org.apache.dubbo.common.compiler.Compiler.class).getAdaptiveExtension();
        // 编译代码,返回该对象
        return compiler.compile(code, classLoader);
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值