代理模式大家应该都非常熟悉了吧,我们的spring中到处使用了代理,比如我们用声明式事物,写一个事物注解,当我们在调用目标对象的某个方法前,spring会先为我们开启一个事物,方法调用结束,spring会为我们提交事物...看起来我们好像是直接使用了目标对象调用了目标方法,而实际上却是使用的spring为我们创建的代理对象...关于这个话题这里不做展开,后续我会写数篇关于spring整个框架原理的解析博文 , 现在,我们举一个简单的例子,来展示下代理模式是怎么工作的!
假设现在你要送给某领导一份礼物,而你与该领导还没有熟悉到送礼物的程度,此时,你可能想要拜托领导的某熟人,让其代替你送礼物...
上面的例子就是一个典型的代理模式, 领导的熟人代替你去给领导送礼物,而他送的礼物的来源实际上还是要借助于你提供礼物...现在我们用代理模式的类结构来组织下代码!
/**送礼物的接口*/
interface SendGift{
//定义送礼物的方法
void send();
}
/**你,目标对象*/
class Clerk implements SendGift{
@Override
public void send() {
System.out.println("送给领导一壶茶");
}
}
/**领导熟人,代理对象*/
class ClerkProxy implements SendGift{
//保存目标对象的引用
private SendGift target;
public ClerkProxy( SendGift target) {
this.target = target;
}
@Override
public void send() {
System.out.println("送礼物前,我先联系好领导");
target.send();
System.out.println("送完礼物后,与领导客套几句并说明这是你送的...");
}
}
public static void main(String[] args) {
SendGift target = new Clerk();
SendGift proxy = new ClerkProxy(target);
proxy.send();
}
输出**************************************************
送礼物前,我先联系好领导
送给领导一壶茶
送完礼物后,与领导客套几句并说明这是你送的...
*******************************************************
Ok,我们看到,代理模式其实很简单,首先由于客户端并不知道自己是在和代理对象打交道,所以代理对象与目标对象必须实现同样的接口,而在代理对象中必须持有目标对象的引用,因为代理对象调用的方法实际上是需要目标(被代理)对象类来提供的, 而代理对象有什么用呢? 就如代码中所示,它在调用目标方法的前后可以加入自己的逻辑处理,这样的逻辑处理就相当于上面提到的事物的开启与提交..
我们画个图来看看代理模式的类结构:
在上面的代码中,Subject就相当于SendGift接口,而Clerk相当于target对象,至于ClerkProxy肯定就相当于proxy对象了;
好了,不多说,设计模式系列的文章到这里也该结束了,值得一提的是,上面的做法是静态代理的实现,而JDK为我们提供了动态代理的实现,关于两者区别以及原理这里就不再多说了,动态代理也非常简单,借助于java.lang.reflect.Proxy的newProxyInstance()便能够实现,这里不再多说,大家可以在网上随意搜索便有一大堆的实例!