代理模式是Java中常用的设计模式,主要由公共接口、被代理类和代理类等三部分组成,代理类持有被代理类的实类,代理为执行具体的类方法。其中代理类与被代理类有同样的接口。
代理类的对象本身并不真正实现服务,而是通过调用被代理类对象的方法来提供特定的服务。
代理分为静态代理和动态代理,编译时能确定被代理的类就是静态, 在运行过程中确定要被代理的类则是动态代理
静态代理
public class daili_demo {
public static void start(a a){
a.echo();
}
public static void main(String[] args){
daili_demo.start(new proxy_subject());
}
}
interface a{
void echo();
}
class real_subject implements a{
public void echo(){
System.out.println("real echo");
}
public static void test(){
System.out.println("test");
}
}
class proxy_subject implements a{
public void echo(){
System.out.println("start");
new real_subject().echo();
new real_subject().test();
System.out.println("end");
}
}
比如上面这段代码实际上proxy_subject和real_subject有相同的接口,proxy_subject即代理类,我们可以在其中调用被代理类的方法,也可以在代理类中实现自己的逻辑,比如在被代理的real_subject的echo调用之前或调用之后添加自己的逻辑
动态代理
在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。在程序运行过程中产生的这个对象,其实就是通过反射机制来生成的一个代理。
每一个动态代理类都必须要实现InvocationHandler这个接口
InvocationHandler
该接口只有一个方法invoke,动态代理类都必须实现该接口,那么也必须要实现该方法,入口参数Object proxy即为要被代理的对象,method为被调用的方法,args为参数
Proxy类
jdk说明中也说了一种简单的方式用于创建动态代理,通过调用Proxy.newProxyInstance函数,proxy类是支持序列化的
import java.lang.reflect.Proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class dongtaidaili_demo {
public static void main(String[] args){
read_object ppp = new read_object();
daili handler = new daili(ppp);
b get_b = (b)Proxy.newProxyInstance(ppp.getClass().getClassLoader(),ppp.getClass().getInterfaces(),handler);
get_b.fun1();
}
}
interface b{
public void fun1();
public void fun2();
}
class read_object implements b{
public void fun1() {
System.out.println("fun1");
}
public void fun2() {
System.out.println("fun2");
}
}
class daili implements InvocationHandler{
private Object subject;
daili(Object subject){
this.subject = subject;
}
public Object invoke(Object object, Method method, Object[] args) throws Throwable {
System.out.println("start");
System.out.println(method);
method.invoke(subject,args);
System.out.println("end");
return null;
}
}

JDK会生成一个叫$Proxy0的代理类,这个类文件是放在内存中的,在创建代理类对象时,通过反射机制获得这个类的构造方法,然后创建代理类实例。
所以整个创建动态代理的流程为首先要声明被代理的接口,然后声明所需要的代理类,然后创建动态代理类,该类要实现invocationhandler接口,然后实现invoke方法,也就是具体的代理处理逻辑,并且要通过该类的构造方法将被代理的对象传进代理类,以便于在invoke函数中进行反射调用。实现代理与被代理的联系是通过newProxyNewinstance,此时要传入classloader,一组接口(就是想要被代理的),以及动态处理类,那么返回的也是一个接口,这个接口可以是一组接口中的任何一个,通过该接口来调用接口内的方法就能够触发动态代理类内部的invoke函数来实现,classloader是sun.misc.Launcher$AppClassLoader,所以最后可以得到jdk中动态代理实际上就是给接口做的代理
