代理的目标:
能够使用动态代理,生成一个代理对象
为什么需要代理:
生活中有很多代理的例子,比如,你要出国旅游,你又很麻烦预办签证,预定机票和酒店,租车那么,我们可以选择旅行社帮我们一条龙操作,这个时候旅行社就是我们的代理,而我们是被代理
代理模式:
被代理者没有能力或者不愿意完成某件事,那么就需要找个人去帮自己完成这件事,这个人就是代理者所以,代理模式中包含了三个角色:分别是被代理者【自己】、代理者【旅行社】、抽象角色【协议】
动态代理:
就是直接通过反射生成一个代理对象,代理对象所属的类是不需要存在的
动态代理的获取:
JDK提供的一个Proxy类,可以直接给实现接口的对象 直接生成一个代理对象
动态代理和静态代理的区别:
静态代理:代理类是真实存在的,通过代理类产生代理对象
动态代理:代理类是不真实存在的,在程序运行过程中,直接产生代理对象
概述:动态代理就是直接通过反射生成一个代理对象,代理对象所属的类是不存在的
动态代理实现获取代理对象:
JDK提供的一个Proxy类,这个类可以直接 给实现接口类的对象【被代理者】 直接生成代理对象【代理者】
例如:使用Proxy直接给Zhangsan生成一个代理对象该对象所属的类不需要知道
java.lang.reflect.Proxy类可以直接生成一个代理对象
- public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
生成一个代理对象
参数1:ClassLoader loader,被代理类的加载器
参数2:Class<?>[] interfaces,被代理类所有实现的接口的Class对象
参数3:InvocationHandler h,执行处理类
前两个参数都是为了帮助在JVM内部生成被代理类的代理对象
前三个参数就是用来监听代理对象调用的方法,帮助我们代理对象调用方法的
代码演示动态代理
public interface Agent {
/*
* 协议,被代理者需要代理的方法,就定义在这个地方,然后让代理者和被代理者都是实现
*
* 被代理者实现:为了确保和代理者实现的方法一致
* 代理者实现:为了增强被代理者的这些方法
* */
// 交易方法
public abstract void agent();
}
public class Zhangsan implements Agent {
@Override
public void agent () {
System.out.println("张三准备买车");
}
}
public class Test {
public static void main (String[] args) {
Zhangsan zhangsan = new Zhangsan();
// 动态代理
Agent agent = (Agent)Proxy.newProxyInstance(Zhangsan.class.getClassLoader(), Zhangsan.class.getInterfaces(), new InvocationHandler() {
@Override
public Object invoke (Object proxy, Method method, Object[] args) throws Throwable {
/*
* invoke(),就是一个回调方法,当代理对象调用了方法,就会来执行该invoke方法,在该方法中就可以增强被代理类的方法
*
* 参数1:Object proxy,生成的代理对象,这里就是happy这个代理对象(不用),这里一旦使用代理对象就会产生递归
* 参数2:Method method,当前代理对象执行的方法,这里的method知道就是happy()方法对象
* 参数3:Object[] args,当前代理对象执行的方法的返回值
* */
//System.out.println("invoke");
// 确保要代理的方法,因为张三可能需要代理多个方法
if(method.getName().equals("agent")){
System.out.println("中介找买、卖家");
// 通过反射来调用被代理的方法
method.invoke(zhangsan);
System.out.println("交易结束");
}
return null;
}
});
// 代理对象,执行happy方法的时候,就会调用上面的增强的方法invoke()
agent.agent();
}
}
运行结果:
中介找买、卖家
张三准备买车
交易结束