深入理解动态代理模式

一、静态代理

很多小伙伴去大城市奋斗,第一件事就是去租房,免不了和中介打交道,因为很多房东很忙,你很可能根本找不到他,从这个场景中就可以抽象出来代理模式:
1.IUserService:被访问者资源的抽象
2.UserServiceImpl:被访问者具体实现类(房东)
3.UserServiceProxy:被访问者的代理实现类(中介)
UML图如下:
在这里插入图片描述
举个例子来理解一下这个设计模式:

老板让记录一下用户服务的响应时间,用代理模式来实现这个功能。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
一切看起来都非常的美好,老板又发话了,把产品服务的响应时间也记录一下吧。又得写如下3个类:

1.IProductService

2.ProductServiceImpl

3.ProductServiceProxy

UserServiceProxy和ProductServiceProxy这两个代理类的逻辑都差不多,却还得写2次。其实这个还好,如果老板说,把现有系统的几十个服务的响应时间都记录一下吧,你是不是要疯了?这得写多少代理类啊?

二、动态代理

在JDK1.3之后引入了一种称之为动态代理(Dynamic Proxy)的机制。使用该机制,我们可以为指定的接口在系统运行期间动态地生成代理对象,从而帮助我们走出最初使用静态代理实现AOP的窘境

动态代理的实现主要由一个类和一个接口组成,即java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。

让我们用动态代理来改造一下上面记录系统响应时间的功能。虽然要为IUserService和IProductService两种服务提供代理对象,但因为代理对象中要添加的横切逻辑是一样的。所以我们只需要实现一个InvocationHandler就可以了。代码如下
在这里插入图片描述
UML图如下。恭喜你,你现在已经理解了Spring AOP是怎么回事了,我们先不展开谈Spring
在这里插入图片描述
先简单谈谈动态代理在Mybatis中是如何被大佬玩的出神入化的

三、Mybatis核心设计思路

相信用过mybatis的小伙伴都能理解下面这段代码,通过RoleMapper这个接口直接从数据库中拿到一个对象

Role role = RoleMapper.getRole(3L);
在这里插入图片描述
ps:entity是javaBean,mapper是接口。

直觉告诉我,一个接口是不能运行的啊,一定有接口的实现类,可是这个实现类我自己没写啊,难道mybatis帮我们生成了?你猜的没错,mybatis利用动态代理帮我们生成了接口的实现类,这个类就是:

org.apache.ibatis.binding.MapperProxy,

那应该就是MapperProxy类把实现类要做的事情做了,MapperProxy通过实现类和SubjectImple.xml之间的映射关系知道自己应该执行什么SQL。所以mybatis最核心的思路就是这么个意思,细节之类的可以看源码,理清最主要的思路,看源码就能把握住重点。

四、小结

1.动态代理非常灵活,可以为任意的接口实现类对象做代理。
2.动态代理可以被代理对象的所有接口的方法做代理。
3.动态代理可以在不改变方法源码的情况下,实现对方法功能的增强。
4.动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java反射机制可以生成任意类型的动态代理类。
5.动态代理同时提高了开发效率。
6.缺点:只能针对接口或者接口的实现类对象做代理对象,普通类是不能做代理对象的。

猜你喜欢

转载自blog.csdn.net/weixin_46011971/article/details/107076551