0%

Java 动态代理(一):静态代理

1. 怎样理解动态代理

  • 动态代理是一种强大的功能,它可以在运行时动态创建一个类,实现一个或多个接口,可以在不修改原有类的基础上动态为通过该类获取的对象添加方法、修改行为
  • 这些特性使得它广泛应用于各种系统程序框架中,比如 Spring、Hibernate、MyBatis、Guice 等
  • 动态代理是实现面向切面的编程 AOP(Aspect Oriented Programming) 的基础。切面的例子有日志、性能监控、权限检查、数据库事务等,它们在程序的很多地方都会用到,代码都差不多,但与某个具体的业务逻辑关系也不太密切,如果在每个用得到的地方都写,代码会很冗余、也难以维护。AOP 将这些切面与主体逻辑相分离,代码就简单优雅得多
  • 动态代理有两种实现方式:一种是 Java SDK 提供的;一种是第三方库(如 cglib)提供的

2. 怎样理解代理这个概念

  • 代理是一个比较通用的词,软件工程中也是一种设计模式
  • 代理背后一般至少有一个实际对象,代理的外部功能和实际对象一般是一样的,用户与代理打交道,不直接接触实际对象

3. 代理存在的价值是

  • 节省成本比较高的实际对象的创建开销,按需延迟加载,创建代理时并不真正创建实际对象,而只是保存实际对象的地址,在需要时再加载或创建
  • 执行权限检查,代理检查权限后,再调用实际对象
  • 屏蔽网络差异和复杂性,代理在本地,而实际对象在其他服务器上,调用本地代理时,本地代理请求其他服务器

4. 写一个静态代理的 Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class SimpleStaticProxyDemo {
static interface IService {
public void sayHello();
}
static class RealService implements IService {
@Override
public void sayHello() {
System.out.println("hello");
}
}
static class TraceProxy implements IService {
private IService realService;
public TraceProxy(IService realService) {
this.realService = realService;
}
@Override
public void sayHello() {
System.out.println("entering sayHello");
this.realService.sayHello(); //代理把方法调用转发给了实际对象
System.out.println("leaving sayHello");
}
}
public static void main(String[] args) {
IService realService = new RealService();
IService proxyService = new TraceProxy(realService);
proxyService.sayHello();
}
}

5. 什么叫静态代理

  • 在上面的 Demo 中,我们想达到的目的是在实际对象的方法调用前后加一些调试语句
  • 为了在不修改原类的情况下达到这个目的,我们在代码中创建了一个代理类 TraceProxy
  • 代理类的代码时在写程序时固定的,所以称为静态代理

6. 代理设计模式和适配器/装饰器设计模式的区别是

  • 三者背后都有一个别的实际对象,都是通过组合的方式指向该对象
  • 不同之处在于,适配器是提供了一个不一样的新接口装饰器是对原接口起到了“装饰”作用,可能是增加了新接口、修改了原有的行为等
  • 代理一般不改变接口,强调它们之间的差别意义不大,可以把适配器和装饰器看作代理的变体,统一看待
-------------------- 本文结束感谢您的阅读 --------------------