动态代理获取方法上的注解(Retrofit框架必备内容)

来源:互联网 发布:北京网络问政平台官网 编辑:程序博客网 时间:2024/06/06 23:54

通过动态代理获取方法,根据方法获取获取方法上的注解和方法参数的注解

  设计的技术包含:动态代理    注解  

  备注:本节内容主要想介绍的是通过如何获取方法体上的注解类型,注解参数

1、添加接口注解

    网络请求方式

<span style="font-size:14px;">@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)public @interface Post {    String value();}</span>

   方法上参数的注解

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

2、 定义接口, 且使用注解的方式在方法上添加网络请求方式,方法参数

public interface Login {        @Post(value = "/appinterface/passport/login.htm")    public void login(@Field(value = "userName") String phone,                      @Field(value = "password") String pwd,                      ICallBack<LoginResponse> callBack);}
3、定义一个回调接口

 由于回调不确定具体类型使用泛型处理

<span style="font-size:14px;">public interface ICallBack<T> {    void success(T t);    void failed(Exception e);}</span>
4、定义一个bean

public class LoginResponse {        String tokenID;    String url;    public String getTokenID() {        return tokenID;    }    public void setTokenID(String tokenID) {        this.tokenID = tokenID;    }    public String getUrl() {        return url;    }    public void setUrl(String url) {        this.url = url;    }}
5、定义动态代理类  (如何获取代理方法上的注解内容)

<span style="font-size:14px;">public class ProxyInfo {        public static <T> T getInfo(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 {                  //方法上的注释及对应的值                Annotation[] annotations = ethod.getAnnotations();                for (int i=0;i<annotations.length;i++){                    if(annotations[i] instanceof  Post){                        System.out.println("确定方法上的类型是post");                    }                    System.out.println("方法上的注解"+annotations[i]);                    System.out.println("方法上的注解值"+((Post)annotations[i]).value());//                    方法的注释@com.ixiaoma.much.Post(value=/appinterface/passport/login.htm)                }                //方法上的参数类型                Type[] parameterTypes = method.getGenericParameterTypes();                for (int i=0;i<parameterTypes.length;i++){                    System.out.println("方法内参数注解"+parameterTypes[i]);                                    }                               //获取的是CallBack内的参数类型LoginResponse</span>               Type type=parameterTypes[parameterTypes.length-1];                ParameterizedType ptype=(ParameterizedType)type;                    Type mType=ptype.getActualTypeArguments()[0];</span>                System.out.println(mType.toString());                                                //方法上参数对应的注解    只有两个有注解                Annotation[][] paraAnno =method.getParameterAnnotations();                int length = paraAnno.length;                int j=0;                for (int i=0;i<length;i++){                    Annotation[] annos = paraAnno[i];   //参数注解类型                    for (Annotation anno: annos) {                        System.out.println("方法上的参数二维数组" + anno+"/"+j);                                                System.out.println("方法上的参数二维数组" + ((Field)anno).value()+"/"+(String)args[j]);                        j++;                    }                }                return null;            }        });    }}</span>

5、定义Test类

Login info = ProxyInfo.getInfo(Login.class);        info.login("18006","654321",new ICallBack<LoginResponse>() {            @Override            public void success(LoginResponse response) {                System.out.println("回调方法执行成功");            }            @Override            public void failed(Exception e) {                System.out.println("执行失败的回调方法");            }        });


执行后,日志显示内容如下:

12368-12368/? I/System.out: 确定方法上的类型是post12368-12368/? I/System.out: 方法上的注解@com.ixiaoma.much.Post(value=/appinterface/passport/login.htm)12368-12368/? I/System.out: 方法上的注解值/appinterface/passport/login.htm12368-12368/? I/System.out: 方法内参数注解class java.lang.String12368-12368/? I/System.out: 方法内参数注解class java.lang.String12368-12368/? I/System.out: 方法内参数注解com.ixiaoma.much.ICallBack<com.ixiaoma.much.LoginResponse>12368-12368/? I/System.out: class com.ixiaoma.much.LoginResponse12368-12368/? I/System.out: 方法上的参数二维数组@com.ixiaoma.much.Field(value=userName)/012368-12368/? I/System.out: 方法上的参数二维数组userName/1800612368-12368/? I/System.out: 方法上的参数二维数组@com.ixiaoma.much.Field(value=password)/112368-12368/? I/System.out: 方法上的参数二维数组password/654321



 

0 0
原创粉丝点击