代理的真相: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