微信公众号:大黄奔跑
关注我,可了解更多有趣的面试相关问题。

文章目录

  • 写在之前
  • 静态代理
  • 动态代理

写在之前

谈到代理模式,最常用的使用场景莫过于 AOP 中的利用了,在讨论 AOP 的实现之前,先来聊聊什么代理模式。

动态代理有两种形式,静态代理和动态代理,大家先不用在意两者的概念,等了解本篇你将会发现其实两者差别不大。

静态代理

用一个简单的例子来分析什么是静态代理,用买房张三卖房这件事儿为例,聊聊代理模式有何作用,为何如此使用如此频繁。

Subject 接口:用于对被访问者的抽象化(比如卖房这件事儿)

SubjectImpl:被访问者的具体实现(张三想要卖房)

SubjectProxy:被访问者的代理实现类,该类需要有一个 Subject 接口具体的实例。(比如房产中介,需要拿着张三授权才可以代理)

Client:访问者的抽象。(比如李四想买房,本身是一个顾客)

代理类本身就是替被访问者做事的,李四想买房子,提了很多要求,比如朝南、学区房;房产中介(SubjectProxy)看张三家的房子刚好符合李四预期,将张三的房子介绍给李四;相当于当一个中间人的意思。有人可能会说,就类似于一个介绍的活儿吗?非得让中介来吗?如果只是简单的介绍,还真不需要中介,但是中介可以帮忙跑贷款、帮忙把握合同等。

这样,张三只需要授权给中介,就可以一边做别的事儿,一边更加省心地完成交易。

上面的图顺理成章变成了如下的模式

被代理的抽象接口——房子

public interface House {/*** 卖房子*/void sell();
}

被访问的类——张三的房子

public class HouseForZhangsan implements House {@Overridepublic void sell() {System.out.println("zhangsan sell house…………");}
}

代理类——房产中介

public class HouseProxy implements House {private House house;// 通过构造方法做到每次替不同的人代理public HouseProxy (House house) {this.house = house;}@Overridepublic void sell() {house = new HouseForZhangsan();house.sell();}
}

测试类——交易场所

public class Test {public static void main(String[] args) {// 构造具体的卖房者House house = new HouseForZhangsan();// 将张三交给中介代理House houseForPerson = new HouseProxy(house);houseForPerson.sell();}
}

还是回到 Spring AOP 模式中,其中 SubjectProxy 就像是 SubjectImpl 的中介,而 SubjectImpl 本身是系统中的 JoinPoint 所在的对象(目标对象),顺理成章地为目标对象创建一个代理对象,完成切面的逻辑。

但是各位想想,市面上并不是只有房子卖呢,张三家里有一辆空闲的车,也想卖,还能去找房产中介吗?

肯定不能了。

于是催生出了专门用于车交易的中介,比如瓜子二手车(号称没有中间商赚差价,哈哈哈)、二手车之家等等。

再比如万一张三突然发现手机用久了,想卖掉二手手机,新的 iPhone,于是又出现了各种各样的二手手机平台(其实本质也是一种中介)

……

……

等等,那有人可能会想,能不能搞一个中介,能够啥都卖呢?于是更加全面的二手平台应运而生了。

在这上面可以灵活的代理各种商品 (被代理对象),这就达到了一种动态中介的效果

对,没错,动态代理已经介绍完了。

开玩笑,继续聊聊 Spring AOP 是如何利用动态代理的。

动态代理

可以指定接口在运行期间动态的生成代理对象。(换句话说:无论你要卖什么,你来的时候都可以给你找一个对应的中介)

那么如何动态生成代理类呢?

需要借助两个工具,一个是 java.lang.reflect.Proxy 类 和 java.lang.reflect.InvocationHandler,问题的关键在于如何实时的给客户产生一个满足要去的中介。

这个就是借助 InvocationHandler来动态生成代理类,还是以上面中介为例,我们姑且讲要生成的代理类叫做 target.

如何动态产生不同类型的中介?

第一步肯定需要知道此时替什么类型客户代理,但是又不能写得太死,我们姑且在生成代理类中先声明一个 被代理的对象。

第二步:通过某种方式将 被代理对象通过传入的方式传进来

第三步:将被代理对象与中介进行绑定。

/*** 被代理的目标*/
public Object target;/*** 绑定委托对象,并且生成代理类* @param target* @return*/
public Object bind(Object target) {this.target = target;//绑定该类实现的所有接口,取得代理类return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}

上述几步部署完成之后,会明白中介要替什么人做事儿,中介做什么事儿,并且将中介与客户关联起来。

最后才是真正的替客户做事儿。

public class SellInvocationHandler implements InvocationHandler {/*** 被代理的目标*/public Object target;/*** 绑定委托对象,并且生成代理类* @param target* @return*/public Object bind(Object target) {this.target = target;//绑定该类实现的所有接口,取得代理类return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {log.info("额外逻辑……");return method.invoke(target, args);}
}

还记得我们之前说过的吗?

动态代理解决的只是灵活产生不同代理类(换句话说灵活搭配不同类型中介)

至于做什么类型事儿,和替什么人做什么事儿这两件事儿还是得存在。

因此仍然需要申明两个类

做什么类型事儿

public interface House {/*** 卖房子*/void sell();
}

替什么人做什么事儿

public class HouseForZhangsan implements House {@Overridepublic void sell() {System.out.println("zhangsan sell house…………");}
}

然后就可以愉快地进行交易了,每次有新的顾客来,就可以叫不同类型的中介来服务。

public class DynamicProxyTest {public static void main(String[] args) {SellInvocationHandler invocationHandler = new SellInvocationHandler();// 将被访问类和代理类相互绑定( 将房产中介 与 房子卖者相互绑定 )House house = (House) invocationHandler.bind(new HouseForZhangsan());// 真正执行house.sell();}
}

至此,我们已经完成了真正的灵活代理工作。

动态代理虽好,却不能解决所有的事情。比如,动态代理只能对实现了相应接口 (Interface) 的类使用,如果某个类没有实现任何的 Interface,就无法使用动态代理机制为其生成相应的动态代理对象。

从法外狂徒张三卖房引起的代理模式相关推荐

  1. 一文彻底搞懂代理模式(Proxy)

    代理模式 引言 代理模式的定义与特点 代理模式的结构 模式实现 静态代理 动态代理 总结 与装饰者模式 文章已收录我的仓库:Java学习笔记与免费书籍分享 代理模式 引言 代理模式是非常常见的模式,在 ...

  2. Java的两大、三类代理模式

    简述 代理,是一种设计模式,主要作用是为其他对象提供一种代理,以控制对这个对象的访问.在某些情况下,一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 主要分 ...

  3. Java动态代理(以现实中我们熟悉的中介代理租房、卖房模式理解)(附案例详解)

    关于代理,在北京生活过的人,第一反应就是中介.因为本人做过中介,所以对其内部运转也较为了解,现在就以中介买卖租赁房屋这个事情来详细地解答一下动态代理的实现.话不多说,上代码:(把代码连同注释复制下来粘 ...

  4. 卖房不必亲自跑腿,交给代理更轻松---代理模式

    博主:爱码叔 个人博客站点: icodebook 公众号:漫话软件设计 专注于软件设计与架构.技术管理.擅长用通俗易懂的语言讲解技术.对技术管理工作有自己的一定见解.文章会第一时间首发在个站上,欢迎大 ...

  5. 帮我们找房租房买房的代理模式

    前言 大家好,看到这个标题大家应该想到了是中介,中介可以帮我们租房找房买房办手续等等,让我们在整个租房买房过程中轻松很多.生活中还有售票黄牛.婚介.经纪人.快递.事务代理.非侵入式日志监听等,都是代理 ...

  6. 又一个创业者自杀:心生郁结,被曝曾卖房给员工发工资

    创业之路到底有多艰难,竟让许多创业者最后走向轻生之路? 2019年12月底,在即将进入新年之际,网传山西好车容易创始人闫宝才于12月26日下午,在家中服用头孢等药物及白酒自杀,后被紧急送往附近医院抢救 ...

  7. 删库跑路大神的一生:曾在家造炸弹被捕,现卖房押宝NFT,原是开源创业之星...

    梦晨 萧箫 发自 凹非寺 量子位 报道 | 公众号 QbitAI "著名开源项目被作者本人删了库"这个瓜,现在是越吃越大了. 「faker.js」和「color.js」的作者Mar ...

  8. rpm打包的流程包括以下哪些_卖房流程包括哪些

    卖方有一定的流程,那卖房流程包括哪些?今日就由PChouse为你一一解答. 1.双方议价.因为房子的价钱不像一般的商品能够计算出成本,价钱高低往往取决于消费者的认定与市场的成交行情. 2.卖方收定金. ...

  9. 2017你该买房,还是卖房?

    一.12月楼市全线降温 国家统计局今日发布的2016年12月70个大中城市住宅销售价格统计数据显示,15个热点城市中,有12个城市新建商品住宅价格环比下降,京沪深一手房房价环比齐跌,只有广州市环比上涨 ...

最新文章

  1. Python 为什么要使用描述符?
  2. tomcat的安装和部署项目
  3. HD_2037今年暑假不AC
  4. PHP面试题:实现中文字串截取无乱码的方法
  5. 1200兆路由器网速_如何选购路由器才能发挥宽带的网速?
  6. linux touch权限不够,Linux下的Access、Modify、Change , touch的使用以及权限问题
  7. 多进程event通信
  8. c性能大容量cket_5千左右预算,既轻薄(高颜值)又高性能的笔记本推荐(畅玩LOL、CF、DNF、流放之路、梦幻西游)...
  9. pulseaudio之pa_simple_new()流程(十八)
  10. HDU 1257 最少拦截系统 简单DP
  11. atitit.安全的签名摘要 算法attilax总结
  12. 什么是PXE及PXE作用
  13. eclipse工具栏全部隐藏
  14. 网站被黑客攻击怎么办?
  15. 计算机桌面来回闪烁,电脑进去桌面就一直闪
  16. Lumen为《堡垒之夜:大逃杀》第四章带来实时全局光照
  17. Memcached分布式算法
  18. sx126x 与 sx127x 的区别
  19. MySQL数据库存储过程
  20. 新闻管理的删除功能+新闻首页+详情页

热门文章

  1. 深拷⻉浅拷⻉的区别?如何实现一个深拷贝?
  2. valgrind和Kcachegrind性能分析工具详解
  3. 如何通过 6 个简单步骤在百度上看到您的网站
  4. 网易2019实习生招聘-牛牛的naozhong
  5. python filelock 文件锁_详解进程文件锁FileLock
  6. 音频信号的基波和谐波介绍
  7. hazelcast 搭建_hazelcast教程 入门
  8. 小学期云效能训练营-Day01
  9. 《数字图像处理》-(3)-1从傅里叶级数到傅里叶变换详细推导以及傅里叶图像的性质
  10. 一道好玩的逻辑题之蓝眼睛红眼睛