自定义retrofit框架(一)java动态代理
2017-12-01 本文已影响1366人
好多个胖子
前言
在开始编写自己的retrofit框架之前,有必要再了解一下java动态代理。因为动态代理在一些成熟的java框架上应用非常广泛,例如android中的 retrofit 以及J2EE中的 mybatise。
这里不讲动态代理的相关类概念,可以自行查找api了解,只是对它在实际开发中的作用进行一个梳理。
动态代理的基本使用
功能一
方法增强,即在一个方法被调用的前后加入额外的操作
#新建一个People的接口,它有一个say的方法
public interface People {
void say();
}
# 新建Man类实现People接口,在say方法中打印hello
public class Man implements People {
@Override
public void say() {
System.out.println("hello");
}
}
#新建 CustomHandler类实现InvocationHandler接口
# 重点关注invoke方法
public class CustomHandler implements InvocationHandler {
private Object target;
public CustomHandler(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("start");
Object obj = method.invoke(target, args);
System.out.println("end");
return obj;
}
}
#执行程序
public class Main {
@Test
public void test1() {
Man people = new Man();
People proxyPeople = (People) Proxy.newProxyInstance(
Man.class.getClassLoader()
, Man.class.getInterfaces()
, new CustomHandler(people));
proxyPeople.say();
}
}
#输出结果
start
hello
end
Process finished with exit code 0
对于Proxy.newProxyInstance()方法不了解的可以自行查找 这里不做介绍
这是一个非常典型的动态代理模式,从代码运行的角度来看,我们仅仅调用了People.say()方法,但是从输出结果来看,在say方法运行之前输出了start,在say之后输出了end,也就是说 我们定义的接口方法say被我们增强了,在它运行之前和之后我们能够加入自己的代码。
功能二
对接口进行实例化,动态代理方式可以在不需要具体实现类的情况下创建接口实例。
#创建People接口
public interface People {
void say();
}
#程序运行
@Test
public void test2() {
People proxyPeople = (People) Proxy.newProxyInstance(
People.class.getClassLoader()
, new Class[]{People.class}
, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("somebody say");
return "";
}
});
proxyPeople.say();
}
#运行结果
somebody say
从上面的代码可以发现,我们只定义了一个接口People,没有实现类,但是通过动态代理创建出了接口的实例并完成了方法People.say()的调用。