代理模式

1 概念

1 定义

为对象提供代理,以控制对这个对象的访问

代理对象在客户端和目标对象之间起到中介作用

分类:静态代理和动态代理

2 应用场景

  • 保护目标对象
  • 增强目标对象

3 优缺点

优点:

  • 代理模式可以将代理对象和目标对象接耦,扩展性好
  • 增强目标对象

缺点:

  • 造成类数目增加
  • 在客户端和目标对象间增加了一个代理对象,会导致请求速度变慢
  • 增加系统复杂度

2 代码实现

场景:发送邮件前进行额外的操作

  • 静态代理

由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。

1
2
3
public interface Email {
public void send();
}
1
2
3
4
5
6
7
8
public class FlashEmail implements Email {

@Override
public void send() {
// TODO Auto-generated method stub
System.out.println("邮件发送中。。。。。");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 代理类
public class EmailProxy implements Email {

Email email;

//传入委托类初始化代理类
public EmailProxy(Email email)
{
this.email=email;
}

@Override
public void send() {
System.out.println("发送邮件前准备。。。");
email.send();
System.out.println("邮件发送后。。。。。。");
}
}
1
2
3
4
5
6
7
8
9
public class Main {

public static void main(String[] args) {
//原始对象
Email email=new FlashEmail();
EmailProxy emailProxy=new EmailProxy(email);
emailProxy.send();
}
}

输出:

发送邮件前准备。。。
邮件发送中。。。。。
邮件发送后。。。。。。

  • 动态代理

    动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。

    java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。这一个类和接口是实现我们动态代理所必须用到的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class EmailDynamicProxy implements InvocationHandler {

Object target;//委托对象

public EmailDynamicProxy(Object obj) {
super();
this.target = obj;
}

public Object bind(){
Class cls = target.getClass();
return Proxy.newProxyInstance(cls.getClassLoader(),cls.getInterfaces(),this);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("发送邮件前准备。。。");
//从委托对象中,调用该对象的指定方法,这里相当于send方法
method.invoke(target);
System.out.println("发送后。。。。。。");
return target;
}
}
1
2
3
4
5
6
7
public class Main {
public static void main(String[] args) {
Email email = new FlashEmail();
Email emailProxy = (Email) new EmailDynamicProxy(email).bind();
emailProxy.send();
}
}

代理模式
http://example.com/代理模式/
作者
Panyurou
发布于
2023年10月5日
许可协议