标签:++ 租房 turn 为我 hang 方法调用 throws 静态代理 src
宁愿做过了后悔,也不要错过了后悔。趁现在还有精力与时间来追求梦想,那就勇敢一些,走出舒适圈,你会看到更美的风景。
今天我们来将一下代理模式(Proxy Pattern),在讲代理模式之前,我们得先知道什么是代理,什么是代理呢,比如你在北京租房子,但是怕被骗,所以你找到了链家,我爱我家这些中介公司帮你找房子,那么链家,我爱我家就是个代理,代理帮你找到合适的房子,再比如,你女朋友今天不在家,但是她的快递来了,所以她就让你帮她取一下,那么你就是你女朋友的代理,其实代理在生活中无处不在,说到这里,你应该对代理有种感觉了吧。
我们学习代理之前,老样子,先得知道它的定义,作用,好处,那么我们才愿意学习它,不然谁会学习它呢?
首先如果你帮你老婆大人干这么些事情,那么老婆大人和你实现的功能是不是一样的?那么该怎么开头呢?对了,委托人(老婆大人)和代理人(你)要实现相同的功能接口。
那么现在我们先来定义一个功能接口:
public interface HouseWork {
public void doheDishes();//洗碗
public void mopFloor();//拖地
public void cook();//做饭
}
OK!,那么以前这些事情都是老婆大人来完成的,那么我们写出老婆大人完成的过程。
public class Wife implements HouseWork {
@Override
public void doheDishes() {
System.out.println("碗洗完了");
}
@Override
public void mopFloor() {
System.out.println("地拖完了");
}
@Override
public void cook() {
System.out.println("饭做好了");
}
}
不好了,这几天老婆大人那几天来了,那么这些任务都是你的了,小伙子。不是,老婆大人不赖也应该帮老婆大人完成一下这些工作啊!!!
public class Husband implements HouseWork {
private Wife wife;
public Husband() {
}
public Husband(Wife wife) {
this.wife = wife;
}
@Override
public void doheDishes() {
wife.doheDishes();
}
@Override
public void mopFloor() {
wife.mopFloor();
}
@Override
public void cook() {
wife.cook();
}
}
我们在看下运行代码:
public class Main {
public static void main(String[] args){
Wife wife = new Wife();
Husband husband = new Husband(wife);
husband.doheDishes();
husband.mopFloor();
husband.cook();
}
}
运行结果:
碗洗完了
地拖完了
饭做好了
哈哈,有没有觉得代理模式很简单啊!那么现在有人要问了,你老公做家务的方法体里面不是都是老婆在做吗?大兄弟别钻牛角尖儿, 学java最大的好处是什么?对,是面向对象,现在做事儿的对象是你,不是你老婆大人,所以,做完这些事儿的人就是你。
说到这里,如果是这样,那么如果张三老婆那几天来了,就得找个代理,李四老婆来了就得请个代理,代码实现起来这得有多少代理呢?那么我找个保姆公司,让保姆公司来做,那么不是就能省去不少的代码了吗??我只能说小伙子,你真厉害,看到了重点。
其实在代码中实现代理的方式分为两种,一种是静态代理,一种是动态代理。
好了,接下来我们用代码实现一下我们的动态代理:
上面我们说了有个保姆公司可以全部把这些事情都做完,那么我们就来写这么一个例子
首先,我们看一下java中Proxy这个类提供创建动态代理的方法
newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
ClassLoader:委托对象的classLoader对象,就是我们的wife对象的classLoader对象
interfaces:功能接口的Class对象
h:我们实现的InvocationHandler
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序。
Ok,话不多说,我们看一下我们自己写的万能InvocationHandler,怎么能变成一个动态代理的关键,我们创建一个保姆公司的万能代理
public class HelpCompany implements InvocationHandler{
private Object object;
public HelpCompany(Object object){
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object o = method.invoke(object,args);
return o;
}
}
好了,这时候就写好了,我们写两个委托对象,张三的老婆大人和李四的老婆大人,同样是做那么几件事
public class LisiWife implements HouseWork {
@Override
public void doheDishes() {
System.out.println("LisiWife碗洗完了");
}
@Override
public void mopFloor() {
System.out.println("LisiWife地拖完了");
}
@Override
public void cook() {
System.out.println("lisiWife饭做好了");
}
}
public class LisiWife implements HouseWork {
@Override
public void doheDishes() {
System.out.println("LisiWife碗洗完了");
}
@Override
public void mopFloor() {
System.out.println("LisiWife地拖完了");
}
@Override
public void cook() {
System.out.println("lisiWife饭做好了");
}
}
接下来,我们看看我们运行的主工程中怎么能动态的代理这两位老婆大人完成她们的工作
public class CompanyMain {
public static void main(String[] args){
ZhangsanWife zhangsanWife = new ZhangsanWife();
ClassLoader zhangsanClassLoader = zhangsanWife.getClass().getClassLoader();
HelpCompany helpCompany = new HelpCompany(zhangsanWife);
HouseWork houseWork = (HouseWork) Proxy.newProxyInstance(zhangsanClassLoader, new Class[]{HouseWork.class}, helpCompany);
houseWork.doheDishes();
houseWork.mopFloor();
houseWork.cook();
LisiWife lisiWife = new LisiWife();
ClassLoader lisiClassLoader = lisiWife.getClass().getClassLoader();
HelpCompany helpCompany_ = new HelpCompany(lisiWife);
HouseWork houseWork_ = (HouseWork) Proxy.newProxyInstance(lisiClassLoader,new Class[]{HouseWork.class},helpCompany_);
houseWork_.doheDishes();
houseWork_.mopFloor();
houseWork_.cook();
}
}
代码很简单
我们来看下运行结果:
ZhangsanWife碗洗完了
ZhangsanWife地拖完了
ZhangsanWife饭做好了
LisiWife碗洗完了
LisiWife地拖完了
lisiWife饭做好了
代理模式到现在我们就讲完了,有没有感觉特别强大!
好了,我们扯点别的,现在Android中有种技术叫做插件话,通过hook技术来将源码中的部分代码用代理执行,在代理中修改自己想定制的内容,但是不会影响整个系统的运行,屌不屌,也许你现在看完这篇文章还不了解,那么就多看几次,看第二遍的想法和看第一遍的想法肯定不一样,相信我哦!源码在底部,学了这么多了,来张美图缓解一下继续我们接下来的学习吧!
源码请用IntelJ打开
源码地址:https://github.com/xingege662/ProxyPattern
标签:++ 租房 turn 为我 hang 方法调用 throws 静态代理 src
原文地址:http://blog.csdn.net/xingege662/article/details/52900804