1.静态代理
目标:
能够使用动态代理 生成一个代理对象
为什么需要代理:
生活中有很多代理的例子,比如,你要出国旅游,你又很麻烦于办签证,预定机票和酒店,租车
那么,我们可以选择旅行社帮我们去一条龙操作,这个时候旅行社就是我们的代理,而我们是被代理
代理模式:
被代理者没有能力或者不愿意完成某件事情,就需要委托他人帮自己完成这件事,这个人就是代理者
所以,代理模式中包含了三个角色:被代理者【自己】、代理者【委托人】、抽象角色【协议】
@案例:
张三要找租车
代理模式的定义:代理者 帮助 被代理者 去做 被代理者不愿意或者没有能力去完成的某件事情,所以代理者去做被代理者的事情
张三 委托 租车公司 去帮 自己 车
定义一个Car类
public interface Car {
/*
* 协议,被代理者需要代理的方法,就定义在这个地方,然后让代理者和被代理者都去实现
*
* 被代理者实现:为了确保和代理者实现的方法一致
* 代理者实现:为了增强被代理者的这些方法
* */
public abstract void car();
}
定义一个张三类
public class Zhangsan implements Car{
@Override
public void car() {
System.out.println("张三在开车");
}
}
定义一个租车公司类
public class Crc implements Car{
//代理者的任务就是帮被代理者去做代理者不愿意去做的事情
//代理者其实就是在帮被代理者增强被代理者想要做的事情
//所以说到增强方法,其实就是使用【装饰者模式】
//成员方法
Zhangsan zhangsan;
//构造方法
public Crc(Zhangsan zhangsan) {
this.zhangsan = zhangsan;
}
@Override
public void car() {
System.out.println("张三在租车公司租了一辆车");
// 张三开始开车
zhangsan.car();
System.out.println("张三开完车把车还回去");
}
}
测试类
public class Tests {
public static void main(String[] args) {
// 不请代理的话,张三直接去找车
Zhangsan zhangsan = new Zhangsan();
//zhangsan.car();
// 找代理
Car crc = new Crc(zhangsan); //crc是代理对象 CRC是代理类 Car接口是协议 zhangsan是被代理对象 Zhangsan是被代理类
crc.car();
/*
* 从以上代码中,我们可以看到,zhangsan的代理对象是 crc,代理对象是确定知道是谁的,所以这种一般本人称之为静态代理
*
* */
}
}
从以上代码中,我们可以看到,zhangsan的代理对象是 crc,代理对象是确定知道是谁的,所以这种一般称之为静态代理
2.动态代理模式
动态代理:
就是直接通过反射生成一个代理对象,代理对象所属的类是不需要存在的
动态代理的获取
JDK提供的一个Proxy类,可以直接给实现接口的对象 直接生成一个代理对象
问题:
张三不方便找车,或者没有渠道找车
张三的car方法需要增强一下
静态代理:代理类是真实存在的,通过代理类产生代理对象
动态代理:代理类是不真实存在的,在程序运行过程中,直接产生代理对象
概述:动态代理就是直接通过反射生成一个代理对象,代理对象所属的类是不需要存在的
提前:
被代理类需要实现接口
动态代理实现获取代理对象
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内部生成被代理类的代理对象
第三个参数就是用来监听代理对象调用的方法,帮助我们代理对象调用方法的
java.lang.reflect.InvocationHandler,是一个接口
定义一个car类
public interface Car {
/*
* 协议,被代理者需要代理的方法,就定义在这个地方,然后让代理者和被代理者都去实现
*
* 被代理者实现:为了确保和代理者实现的方法一致
* 代理者实现:为了增强被代理者的这些方法
* */
public abstract void car();
}
定义一个张三类
public class Zhangsan implements Car {
@Override
public void car() {
System.out.println("张三在开车");
}
}
定义一个测试类
public class Tests {
public static void main(String[] args) {
Zhangsan zhangsan = new Zhangsan();
// 动态代理
Car car = (Car) 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,生成的代理对象,这里就是car这个代理对象(不用),这里一旦使用代理对象就会产生递归
* 参数2: Method method,当前代理对象执行的方法,这里的method指的就是car()方法对象
* 参数3:Object[] args, 当前代理对象执行的方法的返回值
* */
//System.out.println("invoke");
// 确保要代理的方法,因为zhangsan可能需要代理多个方法
if (method.getName().equals("car")) {
System.out.println("张三在租车公司租了一辆车");
// 通过反射来调用被代理对象的方法,调用就是happy()方法,没有参数
method.invoke(zhangsan);
System.out.println("归还");
}
return null;
}
});
// 代理对象car,执行car方法的时候,就会调用上面的增强的方法invoke()
car.car();
}
}