java反射和注解3-仿照retrofit组装接口参数

本片文章将用反射和注解仿照retrofit只需要传入一个带有给定注解的接口,通过调用接口就能直接将传入的数据和注解进行结合,生成对应参数

1,自定义注解

对字段的修饰

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface AnnotationField {
    String value();
}

仿照GET方法注解

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AnnotationGet {
    String value();
}

通过动态代理实现注解和数据拼装

public class RetrofitCopy {

    public  T create(final Class service) {

        return (T) Proxy.newProxyInstance(
                service.getClassLoader(),
                new Class[]{service},
                new AssemblyParametersInvocationHandler()
        );

    }

    private class AssemblyParametersInvocationHandler implements InvocationHandler {

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

            StringBuilder builder = new StringBuilder();

            for (Annotation annotation : method.getAnnotations()) {
                if (annotation instanceof AnnotationGet) {
                    AnnotationGet get = (AnnotationGet) annotation;
                    builder.append(get.value());
                }
            }

            Parameter[] parameters = method.getParameters();

            for (int i = 0; i < parameters.length; i++) {

                Parameter parameter = parameters[i];
                for (Annotation annotation : parameter.getAnnotations()) {
                    builder.append(getParementerAnnotationValue(annotation));
                    builder.append("=");
                }
                builder.append(args[i]);
                if (i < parameters.length - 1) {
                    builder.append("?");
                }

            }
            Log.e("RetrofitCopy", "net: " + builder.toString());

            return null;
        }
    }

    private String getParementerAnnotationValue(Annotation annotation) {
        String data = "";
        if (annotation instanceof AnnotationField) {
            AnnotationField field = (AnnotationField) annotation;
            return field.value();
        }

        return data;

    }
    
}

创建接口api

public interface Api {
    @AnnotationGet("http://baidu.com/")
    void getData(
            @AnnotationField("name")
            String name,
            @AnnotationField("age") int age
    );
}

执行调用代码

 val api = RetrofitCopy().create(Api::class.java);
        api.getData("copyNet1", 1000);
        api.getData("copyNet2", 2000);
        api.getData("copyNet3", 3000);
        api.getData("copyNet4", 4000);
        api.getData("copyNet5", 5000);
        api.getData("copyNet6", 6000);
        api.getData("copyNet7", 7000);

打印数据如下

java反射和注解3-仿照retrofit组装接口参数_第1张图片

这个就是retrofit封装参数的原理,是不是和retrofit一样,只需要接口,然后接口调用方法就可以了

你可能感兴趣的:(java,retrofit,反射,注解,动态代理)