动态代理模式的基本介绍
- 代理对象,不需要实现接口,但是目标对象要实现接口,否则不能用动态代理
- 代理对象的生成,是利用 JDK 的 API,动态的在内存中构建代理对象
- 动态代理也叫做:JDK 代理、接口代理
JDK 中生成代理对象的 API
- 代理类所在包:java.lang.reflect.Proxy
- JDK 实现代理只需要使用 newProxyInstance 方法,但是该方法需要接收三个参数,完整的写法是:
//1. ClassLoader loader : 指定当前目标对象使用的类加载器, 获取加载器的方法固定 //2. Class<?>[] interfaces: 目标对象实现的接口类型,使用泛型方法确认类型 //3. InvocationHandler h : 事情处理,执行目标对象的方法时,会触发事情处理器方法, 会把当前执行的目标对象方法作为参数传入 static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
代码示例
接口
//接口
public interface ITeacherDao {
void teach(); // 授课方法
void sayHello(String name);
}
实现
public class TeacherDao implements ITeacherDao {
@Override
public void teach() {
// TODO Auto-generated method stub
System.out.println(" 老师授课中.... ");
}
@Override
public void sayHello(String name) {
// TODO Auto-generated method stub
System.out.println("hello " + name);
}
}
代理工厂
public class ProxyFactory {
//维护一个目标对象 , Object private Object target;
//构造器 , 对 target 进行初始化
public ProxyFactory(Object target) {
this.target = target;
}
//给目标对象 生成一个代理对象
public Object getProxyInstance() {
//说明
/*
* 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() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
System.out.println("JDK 代理开始~~");
//反射机制调用目标对象的方法
Object returnVal = method.invoke(target, args);
System.out.println("JDK 代理提交");
return returnVal;
}
});
}
}
调用
public class Client {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建目标对象
ITeacherDao target = new TeacherDao();
//给目标对象,创建代理对象, 可以转成 ITeacherDao
ITeacherDao proxyInstance = (ITeacherDao)new ProxyFactory(target).getProxyInstance();
// proxyInstance=class com.sun.proxy.$Proxy0 内存中动态生成了代理对象
System.out.println("proxyInstance=" + proxyInstance.getClass());
//通过代理对象,调用目标对象的方法
//proxyInstance.teach();
proxyInstance.sayHello(" tom ");
}
}