Java代理模式的实现方式

Sylphia 发布于 17 天前 189 次阅读


一、什么是代理模式?

在Java中,使用代理对象来替代原对象来执行一系列操作。就可以在不修改原对象的前提下,对原对象的功能进行扩展和增强。

可以类比一下现实世界的租房,如果要租房的话,你手中掌握的房源信息是比较少的,所以需要先找租房中介,让他去代替你去完成一些操作,然后中介给你提供一些适合你的房源,最后走签订合同等步骤。

二、静态代理

静态代理是通过去手动去创建一个代理类,来对方法进行增强的。

基本步骤:

  1. 定义一个接口及其实现类;
  2. 创建一个代理类同样实现这个接口
  3. 将目标对象注入进代理类,然后在代理类的对应方法调用目标类中的对应方法。

创建流程大概如下图所示:

三、动态代理

动态代理是为了解决静态代理的一些繁琐的步骤的,比如静态代理的话,他需要每一个代理的类都要创建一个xxxProxy这个方法,非常麻烦,而且还要对每个类中的方法去手动增强代码逻辑。

我们也发现了,在创建静态代理的时候,他是在运行前,硬编码到代码里面去实现的,而动态代理他是通过Java反射的这个原理来实现的,也就是运行时来进行实现的。

Java的动态代理主要分为两种,

1.JDK动态代理,这种代理方式是需要代理对象去实现接口才能实现。

2.cglib动态代理,这种代理方式不需要代理对象去实现接口就可以实现。

1.JDK动态代理

Jdk动态代理的实现方法如下:

这里以SmsService这个短信服务为例。

1.创建一个SmsService接口和SmsServiceImpl实现类;
2.创建一个自定义的一个CustomInnovationHandler去实现InnovationHandler;
3.创建一个JdkProxyFactory这么一个类,然后定义一个getProxy()这么一个方法,这个方法里面呢,主要是通过Proxy.newInstanceProxy()这个方法来实现,这个方法通过反射来获取实现类的类加载器、接口信息以及自定义Handler这三个值来创建代理对象。
4.在任意位置,调用JdkProxyFactory.getProxy(new SmsServiceImpl());,就可以创建代理对象来使用了。

以下是创建流程图:

2.cglib动态代理

如果使用Jdk动态代理的话,代理对象必须要实现接口才可以实现。如果代理对象没有实现接口的话,cglib动态代理就可以实现。

cglib动态代理的实现方法如下:

这里还是以SmsService这个短信服务为例。

1.创建一个SmsService非接口类型的类;
2.创建一个自定义方法拦截器CustomMethodInterceptor去实现方法拦截器MethodInterceptor接口;
3.创建一个CglibProxyFactory这么一个类,然后定义一个getProxy()这么一个方法,在这个方法里面,使用new Enhancer()创建Enhancer对象,在这个对象里面设置一些参数:
①获取SmsService的clazz
②使用smsService.getClassLoader()方法获取SmsService的类加载器
③获取咱们之前创建的自定义的方法拦截器
上面都设置完之后,调用enhancer.create()方法创建代理对象并返回。
4.在任意位置,调用CglibProxyFactory.getProxy(SmsService.class);,就可以创建代理对象来使用了。

创建流程图大致如下图所示:

三、动态代理的应用场景有哪些?

1.Spring AOP

AOP可以说是开发过程中最常用的了,比如打印日志的功能,这个功能在写业务代码的时候,每次在每个方法前面或者后面都要写死打印日志的代码会显得很繁琐难以维护,所以使用AOP可以把通用的代码逻辑抽离出来,更加方便维护。

上面我们提到动态代理有两种类型,这两种类型的区别就是,JDK动态代理的话,代理对象必须要实现接口才可以,而cglib动态代理则不需要实现接口就能实现。

所以AOP的实现方式是,如果检测到需要代理的对象实现了接口,那么就使用JDK动态代理,如果没有实现接口那么就使用cglib动态代理来实现。

2.事务注解@Transactional

这个本质上往下层讲是AOP的实现方式,再往下也是动态代理。

加了这个注解,会在底层创建一个事务开启->调用原本代码逻辑->提交/回滚的逻辑。(高亮的部分就是代理对象多做出来的事)

此作者没有提供个人介绍。
最后更新于 2026-08-06