代理模式用的地方比较多,最为熟知的就是spring框架。
今天我们就来聊一聊代理模式,首先代理模式分为静态代理和动态代理。
说下代理模式的思想:
抽象对象(抽象父类或接口):需要完成的功能
被代理对象:隐藏起来的对象
代理对象:显露给其它人的对象,访问被代理对象通过代理对象进行访问
理论的东西都不怎么好理解,这里我进行一个比喻(可能不太恰当,但有助于我们理解并掌握代理模式),我们以租房子为例:
抽象对象,需要完成的功能:租房子这件事
被代理对象:房子的主人房东
代理对象:中介
下面直接上静态代理代码:
Zufang接口:
public interface Zufang {
void zu();
}
Fangdong类:
public class Fangdong implements Zufang {
@Override
public void zu() {
// TODO Auto-generated method stub
System.out.println("出租c02");
}
}
另一个房东类:
public class Fangdong3 implements Zufang{
@Override
public void zu() {
// TODO Auto-generated method stub
System.out.println("出租a09");
}
}
中介:
public class Zhongjie implements Zufang {
//多态,接口定义对象,实现类进行实例化,可以理解为哪个房东租房
private Zufang zufang;
public Zhongjie(Zufang zufang) {
super();
this.zufang = zufang;
}
@Override
public void zu() {
System.out.println("向房东收取中介费");
zufang.zu();
System.out.println("向租客收取中介费");
}
}
Zuke类,其实就是测试类:
public class Zuke {
public static void main(String[] args) {
//租哪个房子,对应的房东不一样啊,
//出租用c02
Zufang zufang = new Fangdong();
//出租a09
Zufang zufang2 = new Fangdong3();
//创建中介对象
Zhongjie zhongjie = new Zhongjie(zufang2);
zhongjie.zu();
}
}
静态代理的缺点:
- 被代理对象和代理对象实现了同一个接口,当抽象接口中增加方法时,不仅被代理对象要增加方法,代理对象也要增加,增加代码维护的复杂度
代理对象只能服务于一种类型的对象,比如上面的租房对象,如果服务多类型的对象,就要为不同的对象创建不同的代理类,就好比说再来一个玩游戏,那个要再创建一个玩游戏的代理类。也就是说代理对象比较多时,代理类也要增加(不增加也可以,但是要在这个代理类中增加代码,实现多个接口),代码相对比较繁琐。
动态代理:
顾名思义,就是当代理对象比较多时,我们的程序也可以动态的去代理它们,说明白点,就是代理对象再多,我们的代理类都不用改动代码。我们今天说的是JDK的动态代理,也是springAOP原理之一。下面直接上代码了,Zufang接口,和其实现类与静态代理的相同,这里不再赘述。
Zhongjie类:
public class Zhongjie implements InvocationHandler{
//中介代表的房东,是一类人,不是一个人
private Object fangdong;
public Object getFangdong() {
return fangdong;
}
public void setFangdong(Object fangdong) {
this.fangdong = fangdong;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("收取房东的中介费");
//System.out.println(method.toString());
Object result = method.invoke(fangdong, args);
System.out.println("收取租客的中介费");
return result;
}
}
Diaoyong类(等同于静态代理中的Zuke):
public class Diaoyong {
public static void main(String[] args) {
//创建一个中介对象
Zhongjie zhongjie = new Zhongjie();
Fangdong fangdong = new Fangdong();
zhongjie.setFangdong(fangdong);
//第一行,执行时给Zufang接口创建临时代理对象Proxy
Zufang zufang = (Zufang) Proxy.newProxyInstance(Diaoyong.class.getClassLoader(), new Class[]{Zufang.class}, zhongjie);
/*第二行,执行时调用Zhongjie中invoke方法,把zufang()方法(一个Method类型的对象)对象赋值给invoke方法第二个参数method,
* 还将zufang()方法参数赋值invoke()方法第三个参数Object,执行invoke方法
*/
zufang.zufang();
}
}
以上就是我对于java代理模式的理解及总结,有理解不到位的地方,欢迎指出,谢谢。