1.静态代理基本介绍:
静态代理,需要定义接口或父类,代理对象和被代理对象实现相同接口或者是继承相同父类,像之前博文中写的代理模式就是静态代理 静态代理例子
2.动态代理的基本介绍:
代理对象不需要实现接口,但是被代理对象要实现接口,否则不能使用动态代理
代理对象的生成,可以利用JDK的api,动态的在内存中构建代理对象。
下面讲一下JDK的动态代理:
JDK的动态代理依靠反射来实现,代理类和被代理类不需要实现同一个接口。被代理类需要实现接口,否则无法创建动态代理。代理类在JVM运行时动态生成,而不是编译期就能确定。
JDK中生成代理对象的代理类所在的包为:java.lang.reflect.Proxy只需要调用newProxyInstance方法接收三个参数即可。
具体实例代码及注释讲解:
//被代理类
class ReTeacher implements Teacher {
public void teach() {
System.out.println(" 老师授课中.... ");
}
public void sayHello(String name) {
System.out.println("hello " + name);
}
}
//需要实现的接口
interface Teacher {
void teach(); // 授课方法
void sayHello(String name);
}
//代理类
class ProxyFactory {
//维护一个目标对象 , Object
private Object target;
//构造器 , 对target 进行初始化
public ProxyFactory(Object target) {
this.target = target;
}
//给目标对象 生成一个代理对象
public Object getProxyInstance() {
//Proxy中的newProxyInstance方法说明
// public static Object newProxyInstance(ClassLoader loader,
// Class<?>[] interfaces,
// InvocationHandler h)
//1. ClassLoader loader : 指定当前目标对象使用的类加载器, 获取加载器的方法固定
//2. Class<?>[] interfaces: 目标对象实现的接口类型,使用泛型方法确认类型
//3. InvocationHandler h : 事情处理,执行目标对象的方法时,会触发事情处理器方法, 会把当前执行的目标对象方法作为参数传入
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("JDK代理开始~~");
//反射机制调用目标对象的方法
Object returnVal = method.invoke(target, args);
System.out.println("JDK代理提交");
return returnVal;
}
});
}
}
class Client3 {
public static void main(String[] args) {
//创建被代理类对象
Teacher target = new ReTeacher();
//给被代理类对象,创建代理对象, 可以转成 Teacher
Teacher proxyInstance = (Teacher)new ProxyFactory(target).getProxyInstance();
// proxyInstance=class com.sun.proxy.$Proxy0 内存中动态生成了代理对象
System.out.println("proxyInstance=" + proxyInstance.getClass());
//通过代理对象,调用被代理类对象的方法
//proxyInstance.teach();
proxyInstance.sayHello(" tom ");
}
}
output:
建议自己Debug去看下动态的代理对象是怎么生成的,以及如何通过动态代理对象调用被代理对象的
方法。