代理模式

代理模式

代理模式是之前学到的,在这里进行一个系统性的复习,因为前边学的代理模式理解并不深刻,但是代理模式又是SpringAOP的底层逻辑,因此需要重新学习。

代理模式的分类:

  • 静态代理模式
  • 动态代理模式

静态代理模式

代理模式十分抽象,因此我们引用房东–房屋中介–租户模型来解释这个关系

房东--房屋中介--租户模型

代理中的角色分析:

  • 抽象角色:一般会使用接口或者抽象类来解决
  • 真实角色:被代理的角色
  • 代理角色:代理真实角色,代理真实角色后一般会有一些附属操作
  • 客户:访问代理对象的人

代理模式的好处:

  • 可以使真实角色的操作更加纯粹,不用去关心一些公共业务
  • 公共事务交给代理角色去处理,实现了业务的分工
  • 公共月舞发生拓展是,方便集中管理

下边我们就用这个模型来模拟一下静态代理模式,看是否与上述特点相同:

模型的搭建:

模型的结构

代码:

抽象接口rent

1
2
3
4
5
6
7
package com.dwx.test01;

public interface rent {
//这是房东和中介都要进行的抽象角色(租房)
void rent();
}

房主Host

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
29
30
31
32
33
34
35
package com.dwx.test01;

public class Host implements rent{
//对于房东 房东可以有自己的属性 比如这里我们给他属性name
String name;
//房东的抽象角色 出租房屋

@Override
public void rent() {
System.out.println(name+"房东要出租房");
}

public Host(String name) {
this.name = name;
}

public Host() {
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "Host{" +
"name='" + name + '\'' +
'}';
}
}

中介Mid

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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package com.dwx.test01;

public class Mid implements rent {
//这里是中介 是中间代理环节
//中介代理房东 因此中介有一个属性是房东
private Host host;
//中介同样要出租房 ,也要继承接口

@Override
public void rent() {
//因为中介是代理房东租房,因此实质上出租房子的还是房东
//因此这里调用房东出租的方法
host.rent();
}

//中介除了执行出租方外,还可以带领住户看房以及签合同,收中介费,因此这些都是中介特有的
//但是是属于每次租房都要干的,是公共的
public void sign() {
System.out.println("中介在签合同");
}

public void see() {
System.out.println("中介在看房");
}

public void fare() {
System.out.println("中介收取中介费");
}

public Mid(Host host) {
this.host = host;
}

public Mid() {
}

public Host getHost() {
return host;
}

public void setHost(Host host) {
this.host = host;
}

@Override
public String toString() {
return "Mid{" +
"host=" + host +
'}';
}
}

中介中心Center

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.dwx.test01;

public class Center {
//这里是中介中心,用户访问的地方
public static void main(String[] args) {
//首先创建一个租户
Host dwx = new Host("dwx");
//再创建一个中介
Mid mid = new Mid();
//给中介分配租户
mid.setHost(dwx);
//中介执行租房操作
mid.see();
mid.sign();
mid.rent();
mid.fare();
}
}

执行结果:

1
2
3
4
中介在看房
中介在签合同
dwx房东要出租房
中介收取中介费

对这个模型进行分析

  • 抽象角色:一目了然,房主和中介都要租房,因此出租房子是抽象角色(用的是抽象接口)
  • 真实角色:房东,是真实被代理的角色,租房是被代理的权利
  • 代理角色:中介,中介除了做抽象角色租房子外,还有签合同等附属操作
  • 客户:访问代理对象

该模型好处的分析

  • 业务分离,中介办理里租房的大部分事情,房主只需要出租房屋
  • 房主的操作更加纯粹
  • 如果中介还要进行其他的服务,容易管理

动态代理模式

动态代理模式继承了静态代理模式的所有优点以及他的代理角色。

但是不同点是:动态代理的代理对象是动态生成的,并且代码十分简短

一般简短的代码在理解起来都很难

对于动态代理,需要了解两个类Proxy类InvocationHander类

这两个类是动态代理的核心,动态代理的绝大多是代码都是固定死的,只要输入参数通过反射机制获取参数,动态创建对象。

InvocationHander类

这个类是实例化调用的处理程序实现的接口

这个类只用一个invoke(proxy,args)方法,这个方法不用我们手动执行,在这个类被加载的时候就默认执行了。

Proxy类

Proxy类提供了创建的动态代理类和实例的静态方法


还是通过这个租房模型,通过动态代理来实现

动态代理类的组成

  • 抽象代理对象:一个抽象接口
  • 创建一个动态代理类继承实现InvocationHandler对象
  • 在这个类中设置我们的rent
  • 在这个类中获得Proxy

完整的动态代理类

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
package com.dwx.test02;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class InvocationHanderProxy implements InvocationHandler {
//对于代理角色 需要抽象对象
private Rent rent;

//设置抽象接口
public void setRent(Rent rent) {
this.rent = rent;
}

//对于动态代理需要获得Proxy
public Object getProxy(){
//这里也是固定的 底层原理是反射
return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(),this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//这里只需要两个参数:args(不变)和rent(我们的抽象类)
return method.invoke(rent, args);
}
}

此时的测试类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.dwx.test02;

public class test {
public static void main(String[] args) {
//现在动态代理类以及全部创建结束
//对于动态代理 需要代理对象
Host dwx = new Host("dwx");
//但是动态代理暂时没有代理对象 需要创建
InvocationHanderProxy ip = new InvocationHanderProxy();
ip.setRent(dwx);
Rent proxy = (Rent) ip.getProxy();
//此时的动态代理对象就生成了
proxy.rent();
}
}

这几步也是固定的不用更改;

Donate
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2015-2023 dwx
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信