教你实现一个简易版的retrofit(最基本原理实现)

代理的真相:https://mp.weixin.qq.com/s/AiZqQjXdkK0k0gekiBIVFg

**************************************************************************************************
//当你写下下面接口代码时候
public interface IUserService{
    Object login(String username, String password);
}

//当你生成代理对象时候
public class Test{
    public static void main(String[] args){
    
        IUserService userService = (IUserService) Proxy.newProxyInstance(IUserService.class.getClassLoader(),
                new Class[]{IUserService.class},
                new InvocationHandler() {
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        System.out.println("method = " + method.getName() +" , args = " + Arrays.toString(args));
                        return null;
                    }
                });

        userService.login("zhy","123");
    }
}

//那么实际jdk帮我们生成的代码呢,哈哈,如下:

public class Proxy{
    protected InvocationHandler h;
}

public final class $Proxy0 extends Proxy implements IUserService{

    public $Proxy0(InvocationHandler invocationhandler){
        super(invocationhandler);
    }
    
    public final Object login(String s, String s1){
        return super.h.invoke(this, m3, new Object[] {
            s, s1
        }); 
    }
    
    private static Method m3;
    
    static {
        m3 = Class.forName("IUserService").getMethod("login", new Class[] {
            Class.forName("java.lang.String"), Class.forName("java.lang.String")
        });
    }
    
}

下面正式开始实现基本的一个retrofit:

package ProxyTest;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 
* @ClassName: ProxyAnnotationTest
* @Description: TODO(注解方法上面)
* @author hsj
* @email 2356899074@qq.com
* @date 2019年6月25日
*
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ProxyAnnotationTest {
	
	String value() default "";
	
}

package ProxyTest;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 
* @ClassName: ProxyAnnotationTest
* @Description: TODO(注解方法参数上面)
* @author hsj
* @email 2356899074@qq.com
* @date 2019年6月25日
*
 */
@Target({ElementType.PARAMETER, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ParamAnnotationTest {
	
	String value() default "";	
	
}
package ProxyTest;
/**
 * 
* @ClassName: Person
* @Description: TODO(接口类,类似retrofit接口类)
* @author hsj
* @email 2356899074@qq.com
* @date 2019年6月25日
*
 */
public interface Person {
  @ProxyAnnotationTest("http://localhost:8080/{whatApplicationName}/index.html")
  CallBackQueue myRetrofit(@ParamAnnotationTest("whatApplicationName") String whatApplicationName);
}

package ProxyTest;
/**
 * 
* @ClassName: CallbackInterface
* @Description: TODO(回调接口成功与否-业务端)
* @author hsj
* @email 2356899074@qq.com
* @date 2019年6月25日
*
 */
public interface CallbackInterface {
	
	//请求成功回调
    public void onResponse(String responceBack);

    //请求与失败回调
    public void onFailure(String responceBack);
    
}

package ProxyTest;
/**
* 
* @ClassName: CallBackQueue
* @Description: TODO(回调队列模拟)
* @author hsj
* @email 2356899074@qq.com
* @date 2019年6月25日
*
*/

public class CallBackQueue{
	private CallbackInterface callbackInterface;

	public CallBackQueue() {
		super();
	}
	
	public void enqueue(CallbackInterface callbackInterface){
		this.callbackInterface = callbackInterface;
	}
	
	@SuppressWarnings("unused")
	public void callBackExecuteResponse(String successResponce){
		if(callbackInterface != null){
			callbackInterface.onResponse(successResponce);
		}
	}
	
	public void callBackExecuteFailure(String fialResponce){
		if(callbackInterface != null){
			callbackInterface.onFailure(fialResponce);
		}
	}
}

package ProxyTest;

import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.concurrent.TimeUnit;

/**
 * 
 * @ClassName: PersonProxyBuiler
 * @Description: TODO(产生代理对象,类似retrofit接口类产生)
 * @author hsj
 * @email 2356899074@qq.com
 * @date 2019年6月25日
 *
 */
public class PersonProxyBuiler {

	@SuppressWarnings("unchecked")
	public static <T> T buid(Class<T> clazz) {
        
		// 代理实例
		return (T) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[] { clazz },
				new InvocationHandler() {//相当于重写InvocationHandler类
                    
			        //返回给用户设置回调接口类
			        private final CallBackQueue callBackQueue = new CallBackQueue();
			        
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						// System.out.println(proxy instanceof Person);
                         
						// 获取接口注解
						ProxyAnnotationTest aProxyAnnotationTest = method.getAnnotation(ProxyAnnotationTest.class);
						Annotation[][] aAnnotation = method.getParameterAnnotations();
						String url = aProxyAnnotationTest.value();
						String param = null;
						String paramValue = null;

						int i = 0;
						for (Annotation[] an1 : aAnnotation) {
							for (Annotation an2 : an1) {
								if (an2 instanceof ParamAnnotationTest) {
									ParamAnnotationTest aParamAnnotationTest = (ParamAnnotationTest) an2;
									param = aParamAnnotationTest.value();
									paramValue = (String) args[i++];
								}
							}
						}

						System.out.println("代理人操作获取ProxyAnnotationTest注解value=" + url);
						System.out.println("代理人操作获取ParamAnnotationTest注解value:" + param);
						System.out.println("代理人操作获取ParamAnnotationTest注解实际参数value:" + paramValue);
						//拼接参数
						String httpAll = url.replace("{" + param.trim() + "}", paramValue.trim());						
						
						//模拟耗时10s的请求操作执行
						new Thread(new Runnable() {
							
							@Override
							public void run() {
								try {
									System.out.println("代理人操作获取完整http请求httpAll地址:" + httpAll);
									System.out.println("代理人操作获取完整http请求httpAll,模拟http远程数据调用请求...耗时10s开始..." );
									TimeUnit.SECONDS.sleep(10);
									System.out.println("代理人操作获取完整http请求httpAll,模拟http远程数据调用请求...耗时10s结束...");
									//成功操作
									callBackQueue.callBackExecuteResponse("恭喜您,耗时10s执行远程http请求成功返回!");
									
								} catch (InterruptedException e) {
									e.printStackTrace();
								}							
							}
						}).start();
						
						
						return callBackQueue;
					}
				});
	}
}

package ProxyTest;

/**
 * 
* @ClassName: PersonProxyTest
* @Description: TODO(代理对象实现继承了Proxy类,实现了Person接口)
* @author hsj
* @email 2356899074@qq.com
* @date 2019年6月25日
*
 */
public class PersonProxyTest {
   public static void main(String[] args) {
	   //产生代理对象实例
	   Person aPersonProxyInstance = PersonProxyBuiler.buid(Person.class);
	   //类似retrofit的http请求及其回调设置
	   aPersonProxyInstance.myRetrofit("HSJAPP").enqueue(new CallbackInterface(){
           //成功执行逻辑
		   @Override
		   public void onResponse(String responceBack) {
			   System.out.println(responceBack);
			   System.out.println("**********成功时候用户执行的一些操作**********");
		   }
		   //失败执行逻辑
		   @Override
		   public void onFailure(String responceBack) {
			   System.out.println(responceBack);
			   System.out.println("**********失败时候用户执行的一些操作**********");
		   }
		   
	   	});
   }
}

附上gitee.com地址:https://gitee.com/hsjjsh123/JavaEasy2Error/tree/master/JavaEasy2Error/src/ProxyTest

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值