自定义retrofit框架(一)java动态代理

前言

在开始编写自己的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()的调用。

在理解了上述代码实现思路之后,下一篇将正式开始自定义retrofit框架

你可能感兴趣的:(自定义retrofit框架(一)java动态代理)