JAVA的动态代理
代理模式
代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
按照代理的创建时期,代理类可以分为两种。
静态代理:由程序员创建或特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。
动态代理:在程序运行时,运用反射机制动态创建而成。
静态代理:
package
com
.
nx
.
test
.
java
.
proxy
.
static_proxy
.
interfaces
;
public
interface
Work
{
public
void
workIng
(
)
;
public
void
comeOfWork
(
)
;
}
package
com
.
nx
.
test
.
java
.
proxy
.
static_proxy
;
import
com
.
nx
.
test
.
java
.
proxy
.
static_proxy
.
interfaces
.
Work
;
public
class
Worker
implements
Work
{
public
void
comeOfWork
(
)
{
System
.
out
.
println
(
"下班,开始工作!!!!!"
)
;
}
public
void
workIng
(
)
{
System
.
out
.
println
(
"上班,放假!!!!!"
)
;
}
}
package
com
.
nx
.
test
.
java
.
proxy
.
static_proxy
;
import
com
.
nx
.
test
.
java
.
proxy
.
static_proxy
.
interfaces
.
Work
;
public
class
WorkerProxy
implements
Work
{
private
Work
worker
;
public
WorkerProxy
(
Work
worker
)
{
this
.
worker
=
worker
;
}
public
void
comeOfWork
(
)
{
System
.
out
.
println
(
"上班之前!!!!"
)
;
worker
.
workIng
(
)
;
System
.
out
.
println
(
"上班之后!!!!!"
)
;
}
public
void
workIng
(
)
{
System
.
out
.
println
(
"下班之前!!!"
)
;
worker
.
comeOfWork
(
)
;
System
.
out
.
println
(
"下班之后!!!"
)
;
}
}
package
com
.
nx
.
test
.
java
.
proxy
.
static_proxy
;
import
com
.
nx
.
test
.
java
.
proxy
.
static_proxy
.
interfaces
.
Work
;
public
class
Test_static_prox
{
public
static
void
main
(
String
[
]
args
)
{
Work
worker
=
new
Worker
(
)
;
Work
workerPorxy
=
new
WorkerProxy
(
worker
)
;
workerPorxy
.
workIng
(
)
;
System
.
out
.
println
(
"==================="
)
;
workerPorxy
.
comeOfWork
(
)
;
}
}
上
班
之
前
!!!!
上
班
,
开
始
工
作
!!!!!
上
班
之
后
!!!!!
===================
下
班
之
前
!!!
上
班
,
放
假
!!!!!
下
班
之
后
!!!
观察代码可以发现每一个代理类只能为一个接口服务,这样一来程序开发中必然会产生过多的代理,而且,所有的代理操作除了调用的方法不一样之外,其他的操作都一样,则此时肯定是重复代码。解决这一问题最好的做法是可以通过一个代理类完成全部的代理功能,那么此时就必须使用动态代理完成。
再来看一下动态代理:
动态代理 :
package
com
.
nx
.
test
.
java
.
proxy
.
dynamic_proxy
.
interfaces
;
public
interface
BookFacade
{
public
void
addBook
(
)
;
}
package
com
.
nx
.
test
.
java
.
proxy
.
dynamic_proxy
;
import
com
.
nx
.
test
.
java
.
proxy
.
dynamic_proxy
.
interfaces
.
BookFacade
;
/*
* 委托类
*/
public
class
BookFacadeImpl
implements
BookFacade
{
/*
* 委托方法
*/
public
void
addBook
(
)
{
System
.
out
.
println
(
"增加图书方法............."
)
;
}
}
package
com
.
nx
.
test
.
java
.
proxy
.
dynamic_proxy
;
import
java
.
lang
.
reflect
.
InvocationHandler
;
import
java
.
lang
.
reflect
.
Method
;
import
java
.
lang
.
reflect
.
Proxy
;
public
class
BookFacadeProxy
implements
InvocationHandler
{
private
Object
target
;
/**
* 绑定委托对象并返回一个代理类
*
@param
target
*
@return
*/
public
Object
bind
(
Object
target
)
{
this
.
target
=
target
;
//要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)
return
Proxy
.
newProxyInstance
(
target
.
getClass
(
)
.
getClassLoader
(
)
,
target
.
getClass
(
)
.
getInterfaces
(
)
,
this
)
;
}
/**
* 调用方法
*/
public
Object
invoke
(
Object
proxy
,
Method
method
,
Object
[
]
args
)
throws
Throwable
{
Object
result
=
null
;
System
.
out
.
println
(
"增加图书方法之前调用"
)
;
result
=
method
.
invoke
(
target
,
args
)
;
System
.
out
.
println
(
"增加图书方法很之后调用"
)
;
return
result
;
}
}
package
com
.
nx
.
test
.
java
.
proxy
.
dynamic_proxy
;
import
com
.
nx
.
test
.
java
.
proxy
.
dynamic_proxy
.
interfaces
.
BookFacade
;
public
class
Test_dynameic_proxy
{
public
static
void
main
(
String
[
]
args
)
{
BookFacadeProxy
bookFacadeProxy
=
new
BookFacadeProxy
(
)
;
BookFacade
bookFacade
=
(
BookFacade
)
bookFacadeProxy
.
bind
(
new
BookFacadeImpl
(
))
;
bookFacade
.
addBook
(
)
;
}
}
增
加
图
书
方
法
之
前
调
用
增
加
图
书
方
法
.............
增
加
图
书
方
法
很
之
后
调
用