美文网首页
仿Retrofit动态代理获取注解方法上的内容和方法上的参数

仿Retrofit动态代理获取注解方法上的内容和方法上的参数

作者: Android_小马范儿 | 来源:发表于2017-07-18 11:32 被阅读0次

    1.自定义注解

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

    2.定义callback

    public interface ICallBack<T> {
    
        void successed(T t);
    
        void failed(Exception exception);
    }
    

    3.定义返回的对象

    public class AppInfo {
    
        private String appName;
        private String appVersion;
    
    }
    

    4.定义动态代理获取方法上的注解和方法上的参数注解

    package annomation;
    
    import typeinfo.Log;
    
    import java.lang.annotation.Annotation;
    import java.lang.reflect.*;
    import java.util.LinkedHashMap;
    import java.util.Map;
    
    /**
     * Created by xiaoma on 2017/7/18.
     */
    public class CreateServiceFactory {
    
        public static <T> T createService(Class<T> clazz) {
            return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz},
                    new InvocationHandler() {
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                            //获取方法上的注解内容
                            getRequestType(method);
                            //获取方法的参数及类型
                            getRequestParams(method, args);
                            //获取最后一个Callback及返回实例
                            getCallbackInfo(method, args);
                            return null;
                        }
                    });
        }
    
        private static void getCallbackInfo(Method method, Object[] args) {
            Type[] types = method.getGenericParameterTypes();
            //最后一个是Callback类型
            Type type = types[types.length - 1];
            Object obj = args[types.length - 1];
            Type responseType;
            if (obj instanceof ICallBack) {
                if (type instanceof ParameterizedType) {
                    ParameterizedType ptype = (ParameterizedType) type;
                    responseType = ptype.getActualTypeArguments()[0];
                    ICallBack callBack = (ICallBack) obj;
                    Log.sop("responseType=" + responseType + "=callback=" + callBack);
                }
            }
        }
    
        private static void getRequestParams(Method method, Object[] args) {
            Map<String, String> paramsMap = new LinkedHashMap<>();
            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
            Type[] parameterTypes = method.getGenericParameterTypes();
            int j = 0;
            int length = parameterAnnotations.length;
            for (int i = 0; i < length - 1; i++) {
                Annotation[] annotation = parameterAnnotations[i];
                if (annotation != null) {
                    for (Annotation anno : annotation) {
                        if (anno instanceof Field) {
                            String key = ((Field) anno).value();
                            paramsMap.put(key, String.valueOf(args[j]));
                            Log.sop("key=" + key + "=value=" + args[j]);
                        }
                    }
                }
                j++;
            }
        }
    
        private static void getRequestType(Method method) {
            Annotation[] annotations = method.getAnnotations();
            for (Annotation annotation : method.getAnnotations()) {
                if (annotation instanceof Post) {
                    String type = ((Post) annotation).value();
                    Log.sop("请求方式=" + type);
                }
            }
        }
    }
    
    

    5.定义接口

    public interface Login {
    
        @Post("/xiaoma/post")
         void getInfo(@Field(value = "version") String version,@Field(value = "info") String inf,ICallBack<AppInfo> callBack);
    }
    

    6.测试

    public class TestAnnomation {
    
        public static void main(String[] args){
            Log.sop("注解测试");
            Login login = CreateServiceFactory.createService(Login.class);
            login.getInfo("xiaoma", "android", new ICallBack<AppInfo>() {
                @Override
                public void successed(AppInfo appInfo) {
    
                }
    
                @Override
                public void failed(Exception exception) {
    
                }
            });
        }
    
    }
    

    7.测试结果

    注解测试
    请求方式=/xiaoma/post
    key=version=value=xiaoma
    key=info=value=android
    responseType=class annomation.AppInfo=callback=annomation.TestAnnomation$1@1d44bcfa
    

    相关文章

      网友评论

          本文标题:仿Retrofit动态代理获取注解方法上的内容和方法上的参数

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