代理模式

代理模式

viEcho Lv5

具体代码见LocalDemo之shejimoshi模块

代理模式很简单,只要记住以下关键点,简单易实现:

  • 代理类与委托类实现同一接口
  • 在委托类中实现功能,在代理类的方法中中引用委托类的同名方法
  • 外部类调用委托类某个方法时,直接以接口指向代理类的实例,这正是代理的意义所在:屏蔽

代理分为静态代理和动态代理;

静态代理,就是写代码是预先定义好对应的代理类,那么一个接口就对应一个代理类;如果接口方法改变,那么代理类也需要变,n个接口就需要n个代理类;代码臃肿,不美观

动态代理又可以分为cglib动态代理和jdk动态代理;

其中CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑;

而jdk动态代理则是通过 Proxy.newProxyInstance 创建动态代理类;
通过设置系统属性,把生成的代理类保存下来

1
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");

动态代理的例子可以参考此篇博客:

总结:
CgLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CgLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CgLib合适,反之,使用JDK方式要更为合适一些。同时,由于CgLib由于是采用动态创建子类的方法,对于final方法,无法进行代理。

JDK动态代理是在运行时JDK根据class文件的格式动态拼装class文件,并加载到jvm中生成代理对象的。而Cglib动态代理是通过ASM库来操作class文件动态生成代理类的。同时你应该了解到:JDK动态代理是基于java中的接口实现的,Cglib是基于java中的继承实现的

请看例子的实现

1
2
3
4
5
6
7
8
src/
├── main/
│ ├── java/
│ │ └── local/demo/test/shejimoshi/proxy/
│ │ ├── Subject.java # 接口类
│ │ ├── RealSubject.java # 真实对象
│ │ ├── Proxy.java # 代理类
│ │ └── ClientMain.java # 客户端调用示例

1.定义操作接口类

1
2
3
public interface Subject {
void request();
}

2.真实对象实现 操作接口类

1
2
3
4
5
6
public class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject: Handling request.");
}
}

3.代理类实现 操作接口类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Proxy implements Subject {
private RealSubject realSubject;

public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}

@Override
public void request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
System.out.println("Proxy: Checking access before handling request.");
realSubject.request();
System.out.println("Proxy: Logging the time of request.");
}
}

4.客户端调用示例

1
2
3
4
5
6
7
8
public class ClientMain {
public static void main(String[] args) {
RealSubject realSubject = new RealSubject();
Proxy proxy = new Proxy(realSubject);

proxy.request();
}
}

总结:代理类的作用是:屏蔽真实对象的一些细节,比如:权限控制,日志记录,性能监控,缓存,事务控制等;

  • Title: 代理模式
  • Author: viEcho
  • Created at : 2024-01-10 00:00:00
  • Updated at : 2025-02-28 13:03:08
  • Link: https://viecho.github.io/2024/0110/proxy-mode.html
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments