基础编程学习快乐每一天
首页
留言
Siddim.com
当前位置:
首页
>
编程知识库
>
后端开发知识
>
设计模式是什么鬼(代理)
设计模式是什么鬼(代理)
阅读
1
2018-12-03
//本文作者:凸凹里歐
//本文收录菜单栏:《设计模式是什么鬼》专栏中
代理,代表打理,以他人的名义代表委托人打理其本职工作之外或不所能及的事务,达成合作关系并更高效地促成事务完成的目的。例如明星经纪人,他们并没有像明星一样会唱歌、跳舞或演戏,而是替明星打理一些无暇顾及的事务(这并不代表可以代理分外之事),比如推广与宣传,合同谈判啊之类,达成和约后他们才会通知明星去表演。再比如机票销售代理商既不造飞机也不提供乘机服务,他们只负责卖票,代理律师并不会因胜诉获得赔偿金或者败诉受到法律制裁,他们只负责代理打官司,等等等等。
图片来源网络,侵删
生活中还有很多其他实例不胜枚举,但对于做技术的我们,以网络代理举例相信是最合适不过了。
首先,我们上网前得去网络服务提供商(
ISP
)申请互联网宽带业务,于是顺理成章光纤入户,并拿到一个调制解调器,也就是我们俗称的“猫”。好,“猫”实现了互联网访问接口,看代码。
1public
%
20interface
%
20Internet
%
20
%
7B
//%
E4
%
BA
%
92
%
E8
%
81
%
94
%
E7
%
BD
%
91
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
E6
%
8E
%
A5
%
E5
%
8F
%
A3
%
0A2
%
0A3
%
20
%
20
%
20
%
20public
%
20void
%
20access
(
String
%
20url
);%
0A4
%
0A5
%
7D
%
0A
1public
%
20class
%
20Modem
%
20implements
%
20Internet
%
20
%
7B
//%
E8
%
B0
%
83
%
E5
%
88
%
B6
%
E8
%
A7
%
A3
%
E8
%
B0
%
83
%
E5
%
99
%
A8
%
0A2
%
0A3
%
20
%
20
%
20
%
20
@
Override
%
0A4
%
20
%
20
%
20
%
20public
%
20void
%
20access
(
String
%
20url
)%
7B
//%
E5
%
AE
%
9E
%
E7
%
8E
%
B0
%
E4
%
BA
%
92
%
E8
%
81
%
94
%
E7
%
BD
%
91
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
E6
%
8E
%
A5
%
E5
%
8F
%
A3
%
0A5
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E6
%
AD
%
A3
%
E5
%
9C
%
A8
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
EF
%
BC
%
9A
%
22
%
20
%
20url
);%
0A6
%
20
%
20
%
20
%
20
%
7D
%
0A7
%
7D
%
0A
作为调制解调器,一定有上网功能了,用户的电脑只需要用网线连接这只“猫”便接入互联网了。就这么简单么?然而某天我们发现孩子学习时总是偷偷上网看电影玩游戏,于是我们决定对某些网站进行过滤,拒绝黄赌毒侵害未成年。那么,我们需要在客户终端电脑与猫之间加一层代理,用于过滤某些不良网站,最终我们决定购买一款有过滤功能的路由器。
%
201public
%
20class
%
20RouterProxy
%
20implements
%
20Internet
%
20
%
7B
//%
E8
%
B7
%
AF
%
E7
%
94
%
B1
%
E5
%
99
%
A8
%
E4
%
BB
%
A3
%
E7
%
90
%
86
%
E7
%
B1
%
BB
%
0A
%
202
%
0A
%
203
%
20
%
20
%
20
%
20private
%
20Internet
%
20modem
;//%
E6
%
8C
%
81
%
E6
%
9C
%
89
%
E8
%
A2
%
AB
%
E4
%
BB
%
A3
%
E7
%
90
%
86
%
E7
%
B1
%
BB
%
E5
%
BC
%
95
%
E7
%
94
%
A8
%
0A
%
204
%
20
%
20
%
20
%
20private
%
20List
&
lt
;
String
&
gt
;%
20blackList
%
20
=%
20Arrays
.
asList
(%
22
%
E7
%
94
%
B5
%
E5
%
BD
%
B1
%
22
,%
20
%
22
%
E6
%
B8
%
B8
%
E6
%
88
%
8F
%
22
,%
20
%
22
%
E9
%
9F
%
B3
%
E4
%
B9
%
90
%
22
,%
20
%
22
%
E5
%
B0
%
8F
%
E8
%
AF
%
B4
%
22
);%
0A
%
205
%
0A
%
206
%
20
%
20
%
20
%
20public
%
20RouterProxy
()%
20
%
7B
%
0A
%
207
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
modem
%
20
=%
20new
%
20Modem
();//%
E5
%
AE
%
9E
%
E4
%
BE
%
8B
%
E5
%
8C
%
96
%
E8
%
A2
%
AB
%
E4
%
BB
%
A3
%
E7
%
90
%
86
%
E7
%
B1
%
BB
%
0A
%
208
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E6
%
8B
%
A8
%
E5
%
8F
%
B7
%
E4
%
B8
%
8A
%
E7
%
BD
%
91
...%
E8
%
BF
%
9E
%
E6
%
8E
%
A5
%
E6
%
88
%
90
%
E5
%
8A
%
9F
%
EF
%
BC
%
81
%
22
);%
0A
%
209
%
20
%
20
%
20
%
20
%
7D
%
0A10
%
0A11
%
20
%
20
%
20
%
20
@
Override
%
0A12
%
20
%
20
%
20
%
20public
%
20void
%
20access
(
String
%
20url
)%
20
%
7B
//%
E5
%
90
%
8C
%
E6
%
A0
%
B7
%
E5
%
AE
%
9E
%
E7
%
8E
%
B0
%
E4
%
BA
%
92
%
E8
%
81
%
94
%
E7
%
BD
%
91
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
E6
%
8E
%
A5
%
E5
%
8F
%
A3
%
E6
%
96
%
B9
%
E6
%
B3
%
95
%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20for
%
20
(
String
%
20keyword
%
20
:%
20blackList
)%
20
%
7B
//%
E5
%
BE
%
AA
%
E7
%
8E
%
AF
%
E9
%
BB
%
91
%
E5
%
90
%
8D
%
E5
%
8D
%
95
%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20if
%
20
(
url
.
contains
(
keyword
))%
20
%
7B
//%
E6
%
98
%
AF
%
E5
%
90
%
A6
%
E5
%
8C
%
85
%
E5
%
90
%
AB
%
E9
%
BB
%
91
%
E5
%
90
%
8D
%
E5
%
8D
%
95
%
E5
%
AD
%
97
%
E7
%
9C
%
BC
%
0A15
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E7
%
A6
%
81
%
E6
%
AD
%
A2
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
EF
%
BC
%
9A
%
22
%
20
%
20url
);%
0A16
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20return
;%
0A17
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A18
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A19
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20modem
.
access
(
url
);//%
E6
%
AD
%
A3
%
E5
%
B8
%
B8
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
E4
%
BA
%
92
%
E8
%
81
%
94
%
E7
%
BD
%
91
%
0A20
%
20
%
20
%
20
%
20
%
7D
%
0A21
%
7D
%
0A
注意看,在这里路由器代理主要充当代理的角色,和之前的“猫”一样,它同样实现了互联网接口,看似也是有上网功能的,其实不然。第
12
行代码对于互联网访问功能的实现一开始就做了个过滤,如果地址中带有黑名单中的敏感字眼则禁止访问并直接退出,反之则于第
19
行调用“猫”的互联网访问方法,看到了吧,最终还是调用“猫”的上网功能。注意此处为了对“猫”进行控制,代理专为此而生,我们直接于第
7
行实例化它而不是需要别人把它注入进来。好了,孩子现在来上网了,迫不及待运行之。
%
201public
%
20class
%
20Client
%
20
%
7B
%
0A
%
202
%
20
%
20
%
20
%
20public
%
20static
%
20void
%
20main
(
String
%
5B
%
5D
%
20args
)%
20
%
7B
%
0A
%
203
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20Internet
%
20proxy
%
20
=%
20new
%
20RouterProxy
();//%
E5
%
AE
%
9E
%
E4
%
BE
%
8B
%
E5
%
8C
%
96
%
E7
%
9A
%
84
%
E6
%
98
%
AF
%
E4
%
BB
%
A3
%
E7
%
90
%
86
%
0A
%
204
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20proxy
.
access
(%
22http
://
www
.%
E7
%
94
%
B5
%
E5
%
BD
%
B1
.
com
%
22
);%
0A
%
205
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20proxy
.
access
(%
22http
://
www
.%
E6
%
B8
%
B8
%
E6
%
88
%
8F
.
com
%
22
);%
0A
%
206
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20proxy
.
access
(%
22ftp
://
www
.%
E5
%
AD
%
A6
%
E4
%
B9
%
A0
.
com
/
java
%
22
);%
0A
%
207
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20proxy
.
access
(%
22http
://
www
.%
E5
%
B7
%
A5
%
E4
%
BD
%
9C
.
com
%
22
);%
0A
%
208
%
0A
%
209
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
/*%
20
%
E8
%
BF
%
90
%
E8
%
A1
%
8C
%
E7
%
BB
%
93
%
E6
%
9E
%
9C
%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
8B
%
A8
%
E5
%
8F
%
B7
%
E4
%
B8
%
8A
%
E7
%
BD
%
91
...%
E8
%
BF
%
9E
%
E6
%
8E
%
A5
%
E6
%
88
%
90
%
E5
%
8A
%
9F
%
EF
%
BC
%
81
%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E7
%
A6
%
81
%
E6
%
AD
%
A2
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
EF
%
BC
%
9Ahttp
://
www
.%
E7
%
94
%
B5
%
E5
%
BD
%
B1
.
com
%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E7
%
A6
%
81
%
E6
%
AD
%
A2
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
EF
%
BC
%
9Ahttp
://
www
.%
E6
%
B8
%
B8
%
E6
%
88
%
8F
.
com
%
0A13
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
AD
%
A3
%
E5
%
9C
%
A8
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
EF
%
BC
%
9Aftp
://
www
.%
E5
%
AD
%
A6
%
E4
%
B9
%
A0
.
com
/
java
%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
AD
%
A3
%
E5
%
9C
%
A8
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
EF
%
BC
%
9Ahttp
://
www
.%
E5
%
B7
%
A5
%
E4
%
BD
%
9C
.
com
%
0A15
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
*/%
0A16
%
20
%
20
%
20
%
20
%
7D
%
0A17
%
7D
%
0A
在第
3
行处,孩子实例化的不再是“猫”,而是被偷梁换柱的替换为路由器代理了,也就是说大家上网都连接路由器了,而不是直接去连“猫”,这样不但省去了我们拨号的麻烦(路由器帮助拨号)而且孩子再也访问不到乱七八糟的网站了。而这个代理自身其实并不具备访问互联网的能力,它只是简单的调用“猫”上网功能,其存在目的只是为了控制对”猫“的互联访问,对其进行代理而已。
说到这里大家有没有发现这个代理模式是不是与装饰器模式很类似?如果观察
UML
类图关系你会发现几乎一模一样,那这个模式存在的意义何在?其实,代理模式更强调的是对被代理对象的控制,而不是仅限于去装饰目标对象并增强其原有的功能。就像明星的例子一样,如果钱没给够,合同未达成,则不让明星随意作秀。
相信大家已经理解地很通透了吧,这也是我们最常用的代理模式了。其实还有一种叫动态代理,不同之处在于其实例化过程是在运行时完成的,也就是说我们不需要专门针对某个接口去写这么一个代理类,而是根据接口动态生成。
举个例子,让我们先忘掉之前的路由器代理,当我们内网中的上网设备越来越多,路由器的
Lan
口已被占满不够用了,于是我们决定换成交换机,看代码。
1public
%
20interface
%
20Intranet
%
20
%
7B
//%
E5
%
B1
%
80
%
E5
%
9F
%
9F
%
E7
%
BD
%
91
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
E6
%
8E
%
A5
%
E5
%
8F
%
A3
%
0A2
%
0A3
%
20
%
20
%
20
%
20public
%
20void
%
20fileAccess
(
String
%
20path
);%
0A4
%
0A5
%
7D
%
0A
为了保持简单,我们假设这个交换机
Switch
实现了局域网访问接口
Intranet
,请注意这里不是互联网接口
Internet
。
1public
%
20class
%
20Switch
%
20implements
%
20Intranet
%
20
%
7B
%
0A2
%
0A3
%
20
%
20
%
20
%
20
@
Override
%
0A4
%
20
%
20
%
20
%
20public
%
20void
%
20fileAccess
(
String
%
20path
)%
7B
%
0A5
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
E5
%
86
%
85
%
E7
%
BD
%
91
%
EF
%
BC
%
9A
%
22
%
20
%
20path
);%
0A6
%
20
%
20
%
20
%
20
%
7D
%
0A7
%
0A8
%
7D
%
0A
这里进行的是局域网文件访问,比如说是拷贝另一台内网机器上的共享文件,并且我们想保证与之前一样的关键字过滤控制功能,也就是说不管是什么地址都要先通过过滤,怎么复用呢?
到这里让我们思考一下,猫实现的是互联网访问接口,交换机实现的是局域网访问接口,那我们的过滤器代理类到底该怎么写?是实现
Internet
接口呢还是实现
Intranet
接口呢?要么两个都实现?再加进来新的类接口又要不停地改实现类吗?这显然行不通,过滤器无非就是一段过滤逻辑不必来回改动,这违反了设计模式开闭原则。动态代理应时而生,我们来看代码。
%
201public
%
20class
%
20KeywordFilter
%
20implements
%
20InvocationHandler
%
20
%
7B
%
0A
%
202
%
0A
%
203
%
20
%
20
%
20
%
20private
%
20List
&
lt
;
String
&
gt
;%
20blackList
%
20
=%
20Arrays
.
asList
(%
22
%
E7
%
94
%
B5
%
E5
%
BD
%
B1
%
22
,%
20
%
22
%
E6
%
B8
%
B8
%
E6
%
88
%
8F
%
22
,%
20
%
22
%
E9
%
9F
%
B3
%
E4
%
B9
%
90
%
22
,%
20
%
22
%
E5
%
B0
%
8F
%
E8
%
AF
%
B4
%
22
);%
0A
%
204
%
0A
%
205
%
20
%
20
%
20
%
20
//%
20
%
E8
%
A2
%
AB
%
E4
%
BB
%
A3
%
E7
%
90
%
86
%
E7
%
9A
%
84
%
E7
%
9C
%
9F
%
E5
%
AE
%
9E
%
E5
%
AF
%
B9
%
E8
%
B1
%
A1
,%
E7
%
8C
%
AB
%
E3
%
80
%
81
%
E4
%
BA
%
A4
%
E6
%
8D
%
A2
%
E6
%
9C
%
BA
%
E3
%
80
%
81
%
E6
%
88
%
96
%
E6
%
98
%
AF
%
E5
%
88
%
AB
%
E7
%
9A
%
84
%
E4
%
BB
%
80
%
E4
%
B9
%
88
%
E9
%
83
%
BD
%
E6
%
98
%
AF
%
E3
%
80
%
82
%
0A
%
206
%
20
%
20
%
20
%
20private
%
20Object
%
20origin
;%
0A
%
207
%
0A
%
208
%
20
%
20
%
20
%
20public
%
20KeywordFilter
(
Object
%
20origin
)%
20
%
7B
%
0A
%
209
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20this
.
origin
%
20
=%
20origin
;//%
E6
%
B3
%
A8
%
E5
%
85
%
A5
%
E8
%
A2
%
AB
%
E4
%
BB
%
A3
%
E7
%
90
%
86
%
E5
%
AF
%
B9
%
E8
%
B1
%
A1
%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E5
%
BC
%
80
%
E5
%
90
%
AF
%
E5
%
85
%
B3
%
E9
%
94
%
AE
%
E5
%
AD
%
97
%
E8
%
BF
%
87
%
E6
%
BB
%
A4
%
E6
%
A8
%
A1
%
E5
%
BC
%
8F
...%
22
);%
0A11
%
20
%
20
%
20
%
20
%
7D
%
0A12
%
0A13
%
20
%
20
%
20
%
20
@
Override
%
0A14
%
20
%
20
%
20
%
20public
%
20Object
%
20invoke
(
Object
%
20proxy
,%
20Method
%
20method
,%
20Object
%
5B
%
5D
%
20args
)%
20throws
%
20Throwable
%
20
%
7B
%
0A15
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
E8
%
A6
%
81
%
E8
%
A2
%
AB
%
E5
%
88
%
87
%
E5
%
85
%
A5
%
E6
%
96
%
B9
%
E6
%
B3
%
95
%
E9
%
9D
%
A2
%
E4
%
B9
%
8B
%
E5
%
89
%
8D
%
E7
%
9A
%
84
%
E4
%
B8
%
9A
%
E5
%
8A
%
A1
%
E9
%
80
%
BB
%
E8
%
BE
%
91
%
0A16
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20String
%
20arg
%
20
=%
20args
%
5B0
%
5D
.
toString
();%
0A17
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20for
%
20
(
String
%
20keyword
%
20
:%
20blackList
)%
20
%
7B
%
0A18
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20if
%
20
(
arg
.
toString
().
contains
(
keyword
))%
20
%
7B
%
0A19
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20System
.
out
.
println
(%
22
%
E7
%
A6
%
81
%
E6
%
AD
%
A2
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
EF
%
BC
%
9A
%
22
%
20
%
20arg
);%
0A20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20return
%
20null
;%
0A21
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A22
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
7D
%
0A23
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
E8
%
B0
%
83
%
E7
%
94
%
A8
%
E7
%
9C
%
9F
%
E5
%
AE
%
9E
%
E7
%
9A
%
84
%
E8
%
A2
%
AB
%
E4
%
BB
%
A3
%
E7
%
90
%
86
%
E5
%
AF
%
B9
%
E8
%
B1
%
A1
%
E6
%
96
%
B9
%
E6
%
B3
%
95
%
0A24
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20return
%
20method
.
invoke
(
origin
,%
20arg
);%
0A25
%
20
%
20
%
20
%
20
%
7D
%
0A26
%
0A27
%
7D
%
0A
对于这个关键字过滤功能我们不再写到代理类里面了,而是另外写个类并实现
JDK
反射包中提供的
InvocationHandler
接口,于第
9
行注入即将被代理的对象,不管是猫还是交换机什么的它总归是个
Object
,然后在第
14
行实现这个
invoke
调用方法,之后生成的动态代理将来会调进来跑这块的逻辑,很显然我们这里依然保持不变的逻辑,在真实对象方法被执行之前运行了过滤逻辑加以控制。由于传入的参数是被代理对象的方法
method
,以及一堆参数
args
,所以注意这里第
24
行我们要用反射去调用被代理对象
origin
了,最后来看我们如何运行。
%
201public
%
20class
%
20Client
%
20
%
7B
%
0A
%
202
%
20
%
20
%
20
%
20public
%
20static
%
20void
%
20main
(
String
%
5B
%
5D
%
20args
)%
20
%
7B
%
0A
%
203
%
0A
%
204
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
E5
%
A4
%
96
%
E7
%
BD
%
91
%
EF
%
BC
%
88
%
E4
%
BA
%
92
%
E8
%
81
%
94
%
E7
%
BD
%
91
%
EF
%
BC
%
89
,%
E7
%
94
%
9F
%
E6
%
88
%
90
%
E7
%
8C
%
AB
%
E4
%
BB
%
A3
%
E7
%
90
%
86
%
E3
%
80
%
82
%
0A
%
205
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20Internet
%
20internet
%
20
=%
20
(
Internet
)%
20Proxy
.
newProxyInstance
(%
0A
%
206
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20Modem
.
class
.
getClassLoader
(),%
0A
%
207
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20Modem
.
class
.
getInterfaces
(),%
20
%
0A
%
208
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20new
%
20KeywordFilter
(
new
%
20Modem
()));%
0A
%
209
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20internet
.
access
(%
22http
://
www
.%
E7
%
94
%
B5
%
E5
%
BD
%
B1
.
com
%
22
);%
0A10
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20internet
.
access
(%
22http
://
www
.%
E6
%
B8
%
B8
%
E6
%
88
%
8F
.
com
%
22
);%
0A11
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20internet
.
access
(%
22http
://
www
.%
E5
%
AD
%
A6
%
E4
%
B9
%
A0
.
com
%
22
);%
0A12
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20internet
.
access
(%
22http
://
www
.%
E5
%
B7
%
A5
%
E4
%
BD
%
9C
.
com
%
22
);%
0A13
%
0A14
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
//%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
E5
%
86
%
85
%
E7
%
BD
%
91
%
EF
%
BC
%
88
%
E5
%
B1
%
80
%
E5
%
9F
%
9F
%
E7
%
BD
%
91
%
EF
%
BC
%
89
%
EF
%
BC
%
8C
%
E7
%
94
%
9F
%
E6
%
88
%
90
%
E4
%
BA
%
A4
%
E6
%
8D
%
A2
%
E6
%
9C
%
BA
%
E4
%
BB
%
A3
%
E7
%
90
%
86
%
E3
%
80
%
82
%
0A15
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20Intranet
%
20intranet
%
20
=%
20
(
Intranet
)%
20Proxy
.
newProxyInstance
(%
0A16
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20Switch
.
class
.
getClassLoader
(),%
0A17
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20Switch
.
class
.
getInterfaces
(),%
20
%
0A18
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20new
%
20KeywordFilter
(
new
%
20Switch
()));%
0A19
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20intranet
.
fileAccess
(%
22
%
5C
%
5C
%
5C
%
5C192
.
68
.
1
.
2
%
5C
%
5C
%
E5
%
85
%
B1
%
E4
%
BA
%
AB
%
5C
%
5C
%
E7
%
94
%
B5
%
E5
%
BD
%
B1
%
5C
%
5CIronHuman
.
mp4
%
22
);%
0A20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20intranet
.
fileAccess
(%
22
%
5C
%
5C
%
5C
%
5C192
.
68
.
1
.
2
%
5C
%
5C
%
E5
%
85
%
B1
%
E4
%
BA
%
AB
%
5C
%
5C
%
E6
%
B8
%
B8
%
E6
%
88
%
8F
%
5C
%
5CHero
.
exe
%
22
);%
0A21
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20intranet
.
fileAccess
(%
22
%
5C
%
5C
%
5C
%
5C192
.
68
.
1
.
4
%
5C
%
5Cshared
%
5C
%
5CJava
%
E5
%
AD
%
A6
%
E4
%
B9
%
A0
%
E8
%
B5
%
84
%
E6
%
96
%
99
.
zip
%
22
);%
0A22
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20intranet
.
fileAccess
(%
22
%
5C
%
5C
%
5C
%
5C192
.
68
.
1
.
6
%
5C
%
5CJava
%
E7
%
9F
%
A5
%
E9
%
9F
%
B3
%
5C
%
5C
%
E8
%
AE
%
BE
%
E8
%
AE
%
A1
%
E6
%
A8
%
A1
%
E5
%
BC
%
8F
%
E6
%
98
%
AF
%
E4
%
BB
%
80
%
E4
%
B9
%
88
%
E9
%
AC
%
BC
.
doc
%
22
);%
0A23
%
0A24
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
/*%
0A25
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E5
%
BC
%
80
%
E5
%
90
%
AF
%
E5
%
85
%
B3
%
E9
%
94
%
AE
%
E5
%
AD
%
97
%
E8
%
BF
%
87
%
E6
%
BB
%
A4
%
E6
%
A8
%
A1
%
E5
%
BC
%
8F
...%
0A26
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E7
%
A6
%
81
%
E6
%
AD
%
A2
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
EF
%
BC
%
9Ahttp
://
www
.%
E7
%
94
%
B5
%
E5
%
BD
%
B1
.
com
%
0A27
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E7
%
A6
%
81
%
E6
%
AD
%
A2
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
EF
%
BC
%
9Ahttp
://
www
.%
E6
%
B8
%
B8
%
E6
%
88
%
8F
.
com
%
0A28
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
AD
%
A3
%
E5
%
9C
%
A8
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
EF
%
BC
%
9Ahttp
://
www
.%
E5
%
AD
%
A6
%
E4
%
B9
%
A0
.
com
%
0A29
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E6
%
AD
%
A3
%
E5
%
9C
%
A8
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
EF
%
BC
%
9Ahttp
://
www
.%
E5
%
B7
%
A5
%
E4
%
BD
%
9C
.
com
%
0A30
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E5
%
BC
%
80
%
E5
%
90
%
AF
%
E5
%
85
%
B3
%
E9
%
94
%
AE
%
E5
%
AD
%
97
%
E8
%
BF
%
87
%
E6
%
BB
%
A4
%
E6
%
A8
%
A1
%
E5
%
BC
%
8F
...%
0A31
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E7
%
A6
%
81
%
E6
%
AD
%
A2
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
EF
%
BC
%
9A
%
5C
%
5C192
.
68
.
1
.
2
%
5C
%
E5
%
85
%
B1
%
E4
%
BA
%
AB
%
5C
%
E7
%
94
%
B5
%
E5
%
BD
%
B1
%
5CIronHuman
.
mp4
%
0A32
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E7
%
A6
%
81
%
E6
%
AD
%
A2
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
EF
%
BC
%
9A
%
5C
%
5C192
.
68
.
1
.
2
%
5C
%
E5
%
85
%
B1
%
E4
%
BA
%
AB
%
5C
%
E6
%
B8
%
B8
%
E6
%
88
%
8F
%
5CHero
.
exe
%
0A33
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
E5
%
86
%
85
%
E7
%
BD
%
91
%
EF
%
BC
%
9A
%
5C
%
5C192
.
68
.
1
.
4
%
5Cshared
%
5CJava
%
E5
%
AD
%
A6
%
E4
%
B9
%
A0
%
E8
%
B5
%
84
%
E6
%
96
%
99
.
zip
%
0A34
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
E8
%
AE
%
BF
%
E9
%
97
%
AE
%
E5
%
86
%
85
%
E7
%
BD
%
91
%
EF
%
BC
%
9A
%
5C
%
5C192
.
68
.
1
.
6
%
5CJava
%
E7
%
9F
%
A5
%
E9
%
9F
%
B3
%
5C
%
E8
%
AE
%
BE
%
E8
%
AE
%
A1
%
E6
%
A8
%
A1
%
E5
%
BC
%
8F
%
E6
%
98
%
AF
%
E4
%
BB
%
80
%
E4
%
B9
%
88
%
E9
%
AC
%
BC
.
doc
%
0A35
%
0A36
%
20
%
20
%
20
%
20
%
20
%
20
%
20
%
20
*/%
0A37
%
20
%
20
%
20
%
20
%
7D
%
0A38
%
7D
%
0A
可以看到,我们不管是访问互联网还是局域网,只需要分别生成相应的代理并调用即可,相同的过滤器逻辑被执行了。如此一来,我们并不需要再写任何的代理类了,只需要实现一次
InvocationHandler
就一劳永逸了,在运行时去动态地生成代理,达到兼容任何接口的目的。
其实在很多框架中大量应用到了动态代理模式,比如
Spring
的面向切面
AOP
,我们只需要定义好一个切面类@
Aspect
,声明其切入点@
Pointcut
(被代理的哪些对象的哪些方法,也就是这里的猫和交换机的
access
以及
accessFile
),以及被切入的代码块(要增加上去的逻辑,比如这里的过滤功能代码,可分为前置执行@
Before
,后置执行@
After
,以及异常处理@
AfterThrowing
等),于是框架自动帮我们生成代理并切入目标执行。正如给每给方法前后加入日志的例子,或者更经典的事务控制的例子,在所有业务代码之前先切入“事务开始”,执行过后再切入“事务提交”,如果抛异常被捕获则执行“事务回滚”,如此就不必要在每个业务类中去写这些重复代码了,一劳永逸,冗余代码大量减少,开发效率惊人提升。
图片来源网络,侵删
两耳不闻窗外事,一心只读圣贤书,毕竟隔行如隔山,山外之事还是交给专家去代理吧。
点击图片加入
Spring
交流群
↓↓↓
看完本文有收获?请转发分享给更多人
以上数据来源于网络,如有侵权,请联系删除。
上一篇:
面试官:数据量很大的情况下,对于分页查询你有什么优化方案吗?
下一篇:
面试官:你的项目是如何处理重复请求/并发请求的?
评论
(0)
提交
类别
基础编程学习
HTML
PHP
Python
编程知识库
后端开发知识
热门文章
Java并发中的同步容器与并发容器,你了解多少?
Innodb中的事务隔离级别和锁的关系,难倒一半面试者!
SpringBoot + minio实现分片上传、秒传、续传
面试官:你知道消息队列如何保证数据不丢失吗?
JAVA知识 Java8新特性
面试官:谈谈为什么要限流,有哪些限流方案?
说说动态代理与静态代理区别
面试官:思考Tomcat 类加载器为什么要违背双亲委派模型?
boot-admin 基于SpringBoot的后台权限管理系统,可作为脚手架,用于快速搭建项目
SpringBoot+Vue+App+硬件实现智能家居系统项目