美文网首页
动态代理+注释

动态代理+注释

作者: 王灵 | 来源:发表于2022-10-19 16:39 被阅读0次

大家都说retrofit的经典之处就在于动态代理+注释,于是我专门去了解了动态代理和注解。下面开始我的猜想,retrofit的源码太复杂了我看不懂。

1、利用注释创建3个retrofit中的常见自定义注释

FormUrlEncoded.class

@Documented //标记这些注释是否包含在用户文档中
@Target({ElementType.METHOD})//注释用在哪里 方法
@Retention(RetentionPolicy.RUNTIME)//注释怎么保存  RUNTIME*运行时
public @interface FormUrlEncoded {
}

POST.class

@Documented //文档
@Target({ElementType.METHOD})//方法
@Retention(RetentionPolicy.RUNTIME)//运行时
public @interface POST {
    String value() default "";
}

FieldMap.class

@Documented //文档
@Target({ElementType.PARAMETER})//参数
@Retention(RetentionPolicy.RUNTIME)//运行时
public @interface FieldMap {
    boolean encoded() default false;
}

2、创建一个接口类来使用上门的注释,模拟开发中的请求接口定义

PayService.class

interface PayService {
    /**
     * 获取支付配置
     */
    @FormUrlEncoded
    @POST("appsdk/Sdk/GetPayment")
    fun getPayConfig(@FieldMap body: MutableMap<String, Any>): Any

    /**
     * 进行支付
     */
    @FormUrlEncoded
    @POST("appsdk/Sdk/InternalSubmitOrder")
    fun pay(@FieldMap body: MutableMap<String, Any>): Any

}

3、创建动态代理类,并获取对应函数中的注解信息

ServiceProxy.class

class ServiceProxy : InvocationHandler {

    override fun invoke(proxy: Any?, method: Method?, args: Array<out Any>?): Any {
        //获取函数的注释
        if (method?.isAnnotationPresent(FormUrlEncoded::class.java) == true) {
            println("函数有 FormUrlEncoded 注释")
        }
        if (method?.isAnnotationPresent(POST::class.java) == true) {
            var annotation = method.getAnnotation(POST::class.java)
            println("函数有 POST 注释 Value:" + annotation.value)
        }
        method?.apply {
            var parameterAnnotations = parameterAnnotations

            parameterAnnotations.forEach {
                it.forEach { annotation ->
                    println(annotation)
                    if (annotation.annotationClass.simpleName == FieldMap::class.java.simpleName) {
                        println("参数上有 FieldMap 注释")
                    }
                }
            }
        }
        return ""//获取到需要的信息之后,完全可以组合成okhttp请求需要的各种参数
    }

    public fun <T> getServiceProxy(clz: Class<T>): T {
        return Proxy.newProxyInstance(clz.classLoader, arrayOf(clz), this) as T
    }

}

4、创建一个测试类,来看看能否获取到我们想要的信息

Test.kt

object Test {
    @JvmStatic
    fun main(args: Array<String>) {
        val map = mutableMapOf<String, Any>(
            "amount" to "",
            "billno" to ""
        )
        ServiceProxy().getServiceProxy(PayService::class.java).let {
                it.getPayConfig(map)
                it.pay(map)
        }
    }
}

运行结果:


zhushi.jpg

既然能获取到注释的信息,那么我想我们就能利用代理的特效添加后置操作来请求okhttp了。

相关文章

  • 动态代理+注释

    大家都说retrofit的经典之处就在于动态代理+注释,于是我专门去了解了动态代理和注解。下面开始我的猜想,ret...

  • 面试系列~动态代理实现与原理

    动态代理有JDK动态代理, CGLIB动态代理, SpringAOP动态代理 一,JDK动态代理  jdk动态代理...

  • 编程常用的设计模式

    动态代理和静态代理 静态代理 动态代理 静态代理与动态代理的区别 JDK中的动态代理和CGLIB 实现动态代理的方...

  • Spring的AOP原理分析

    一 动态代理 动态代理分为JDK动态代理和CGLIB动态代理 jdk动态代理 被代理类(目标类)和代理类必须实现同...

  • 设计模式之代理模式

    代理分为静态代理和动态代理。 动态代理又包括基于JDK的动态代理、基于CGlib 的动态代理、基于Aspectj实...

  • Java高级主题(五)——动态代理

    代理可以分为静态代理、动态代理,动态代理又可以分为 jvm的动态代理 和 cglib的动态代理。像spring框架...

  • 动态代理

    动态代理分为两类:1、基于接口的动态代理; (JDK动态代理 )2、基于类的动态代理;(cglib动态代理)3、J...

  • 动态代理的两种方式

    静态代理就不说了,基本用到的都是动态代理。 Java中动态代理有JDK动态代理和CGLIB动态代理。 JDK代理的...

  • Java动态代理

    通过以下几种方式介绍动态代理 动态代理涉及到的类 动态代理用法 Proxy类解析 动态代理类解析 动态代理涉及到的...

  • Spring之代理模式

    九、代理模式 目录:静态代理、动态代理AOP的底层机制就是动态代理。代理模式分为静态代理和动态代理。接触aop之前...

网友评论

      本文标题:动态代理+注释

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