一句话 说清楚动态代理 动态的在内存中给被代理对象 创建一个代理类。被代理类不同,创建的代理类不同。所以是动态的
代码实例如下:
工厂类:
public class ProxyFactory {
//维护一个 被代理类 对象 用 Object 就可以了因为不知道 被代理类是那样的。 通过 构造器 初始化 属性
private Object target;
// 利用构造器对 代理对象 进行初始化
public ProxyFactory(Object target) {
this.target = target;
}
//给目标对象生成一个代理对象
/**三个参数的说明:
* classLoder 类加载器,代理类被加载的时候需要使用类加载器。这里一般是应用类加载器
* interfaces[] 我们给这个代理对象提供了一组什么接口,那么我这个代理对象就会实现了这组接口
* handler 调用处理器 实现了 InvocationHandler 这个接口的匿名实现类。重写方法
* 这个方法里面利用反射 调用 被代理类的方法。
* 1、为什么我们这里可以将其转化为ITeachDao类型的对象?
* 原因就是在newProxyInstance这个方法的第二个参数上,
* 我们给这个代理对象提供了一组什么接口,那么我这个代理对象就会实现了这组接口,
* 这个时候我们当然可以将这个代理对象强制类型转化为这组接口中的任意一个,
* 因为这里的接口是ITeachDao类型,所以就可以将其转化为ITeachDao类型了。
*
* 同时我们一定要记住,通过 Proxy.newProxyInstance 创建的代理对象是在jvm运行时动态生成的一个对象,
* 它并不是我们的InvocationHandler类型,也不是我们定义的那组接口的类型,而是在运行是动态生成的一个对象,
* 并且命名方式都是这样的形式,以$开头,proxy为中,最后一个数字表示对象的标号。
*
*
*/
public Object getProxyInstance(){
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 val = method.invoke(target,args);
return val;
}
});
}
接口:
public interface ITeachDao {
void teach();
}
被代理对象:
public class Teacher implements ITeachDao {
public void teach() {
System.out.println("老师正在授课");
}
}
测试 客户端:
//一句话 说清楚动态代理 动态的在内存中给被代理对象 创建一个代理类。被代理对象不同创建的 代理类不同。
public class Client {
public static void main(String[] args) {
//创建 被代理类
Teacher target = new Teacher();
//给被代理类 创建 代理对象
ProxyFactory factory = new ProxyFactory(target);
ITeachDao proxyInstance =(ITeachDao) factory.getProxyInstance();
System.out.println("proxyInstance=" + proxyInstance.getClass()); //com.sun.proxy.$Proxy0
//代理对象 调用 方法。
proxyInstance.teach();
}
}
说明
/**
*
*
*
* 代理类和被代理类 都实现了同一个接口,这个是他们俩能产生关联的唯一地方。
*
* public static Object getProxyInstance() 这个Object 是一个proxy类,和 被代理类不是同一个类型
*
* 缺点:如果被代理类没有实现任何接口则没有办法创建代理类
*
*/
Proxy理解
通过学习动态代理接触到了Proxy这个类,这个类用的最多的就是newProxyInstance 这个方法,用来创建代理类,AOP底层就是动态代理