随笔:93 文章:11 评论:22 引用:0
My Rhythm
万物皆对象 万事归节奏
首页
发新随笔
发新文章
联系
聚合
管理
[转]Java 静态代理和动态代理
载自http://kuangbaoxu.javaeye.com/blog/192804
1. 代理模式主要有两种:静态代理和动态代理
2. 静态代理:
比如要在输出“HelloWorld”前打印一个字符串“Welcome”
A:先定义一个接口类
1
package
ttitfly.proxy;
2
3
public
interface
HelloWorld
{
4
public
void
print();
5
//
public void say();
6
}
B: 定义一个该接口的实现类
java 代码
1
package
ttitfly.proxy;
2
3
public
class
HelloWorldImpl
implements
HelloWorld
{
4
5
public
void
print()
{
6
System.out.println(
"
HelloWorld
"
);
7
}
8
//
public void say(){
9
//
System.out.println("Say Hello!");
10
//
}
11
}
C:定义一个静态代理类
1
package
ttitfly.proxy;
2
3
public
class
StaticProxy
implements
HelloWorld
{
4
5
public
HelloWorld helloWorld ;
6
public
StaticProxy(HelloWorld helloWorld)
{
7
this
.helloWorld
=
helloWorld;
8
}
9
10
public
void
print()
{
11
System.out.println(
"
Welcome
"
);
12
//
相当于回调
13
helloWorld.print();
14
}
15
16
//
public void say(){
17
//
//
相当于回调
18
//
helloWorld.say();
19
//
}
20
}
D: 一个测试类:
1
package
ttitfly.proxy;
2
3
public
class
TestStaticProxy
{
4
5
public
static
void
main(String[] args)
{
6
HelloWorld helloWorld
=
new
HelloWorldImpl();
7
StaticProxy staticProxy
=
new
StaticProxy(helloWorld);
8
staticProxy.print();
9
10
//
staticProxy.say();
11
}
12
}
可以看出静态代理类有一个很不爽的缺点:当如果接口加一个方法(把上面所有的代码的注释给去掉),所有的实现类和代理类里都需要做个实现。这就增加了代码的复杂度。动态代理就可以避免这个缺点。
3 。动态代理
动态代理与普通的代理相比较,最大的好处是接口中声明的所有方法都被转移到一个集中的方法中处理(invoke),这样,在接口方法数量比较多的时候,我们可以进行灵活处理,而不需要像静态代理那样每一个方法进行中转。
动态代理类只能代理接口,代理类都需要实现InvocationHandler类,实现invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法返回的值是被代理接口的一个实现类
代理类:
1
package
ttitfly.proxy;
2
3
import
java.lang.reflect.InvocationHandler;
4
import
java.lang.reflect.Method;
5
import
java.lang.reflect.Proxy;
6
//
动态代理类只能代理接口,代理类都需要实现InvocationHandler类,实现invoke方法。该invoke方法就是调用被代理接口的所有方法时需要调用的,该invoke方法返回的值是被代理接口的一个实现类
7
public
class
DynamicProxy
implements
InvocationHandler
{
8
9
private
Object object;
10
//
绑定关系,也就是关联到哪个接口(与具体的实现类绑定)的哪些方法将被调用时,执行invoke方法。
11
//
Proxy.newProxyInstance的第三个参数是表明这些被拦截的方法执行时需要执行哪个InvocationHandler的invoke方法
12
public
Object bindRelation(Object object)
{
13
this
.object
=
object;
14
return
Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(),
this
);
15
}
16
//
拦截关联的这个实现类的方法被调用时将被执行
17
public
Object invoke(Object proxy, Method method, Object[] args)
throws
Throwable
{
18
System.out.println(
"
Welcome
"
);
19
Object result
=
method.invoke(object, args);
20
return
result;
21
}
22
23
}
测试类:
1
package
ttitfly.proxy;
2
3
public
class
TestDynamicProxy
{
4
public
static
void
main(String[] args)
{
5
HelloWorld helloWorld
=
new
HelloWorldImpl();
6
DynamicProxy dp
=
new
DynamicProxy();
7
//
在这里绑定的是HelloWorld,也就是HelloWorld是被代理接口。所以绑定关系时,需要传递一个HelloWorld的实现类的实例化对象。
8
HelloWorld helloWorld1
=
(HelloWorld)dp.bindRelation(helloWorld);
9
helloWorld1.print();
10
helloWorld1.say();
11
12
//
helloWorld2将不被拦截
13
HelloWorld helloWorld2
=
new
HelloWorldImpl();
14
helloWorld2.print();
15
helloWorld2.say();
16
17
}
18
}
在测试类里调用实现类的print和say方法,因为代理类里代理了HelloWorld的所有方法。所以就不需要像静态代理类那样一一实现了。
[本来想自己写个类似的东西,不过发现javaeye的这篇写的已经很好了.转载过来学习一下.
javaeye的代码copy功能真好用!.]
发表于 2009-02-17 18:40
redcoatjk
阅读(370)
评论(1)
编辑
收藏
评论
#
re: [转]Java 静态代理和动态代理
动态代理 没接触过.看起来有点puzzle
..多看几次吧..
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
知识库
C++博客
博问
管理
CALENDER
<
2009年2月
>
日
一
二
三
四
五
六
25
26
27
28
29
30
31
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
1
2
3
4
5
6
7
常用链接
我的随笔
我的评论
我的参与
最新评论
留言簿
(3)
给我留言
查看公开留言
查看私人留言
随笔分类
(22)
balabala(2)
(rss)
Database(9)
(rss)
Hibernate(1)
(rss)
J2se(5)
(rss)
Others_4Data Persistence(2)
(rss)
Spring(1)
(rss)
View_lever(2)
(rss)
随笔档案
(76)
2014年3月 (1)
2013年11月 (1)
2013年4月 (1)
2012年9月 (1)
2012年7月 (3)
2012年6月 (1)
2012年2月 (2)
2011年11月 (2)
2011年10月 (1)
2011年8月 (5)
2011年6月 (1)
2011年5月 (3)
2011年2月 (1)
2010年8月 (2)
2010年7月 (2)
2010年6月 (2)
2010年5月 (3)
2010年3月 (3)
2009年11月 (2)
2009年10月 (2)
2009年9月 (1)
2009年7月 (2)
2009年5月 (12)
2009年4月 (2)
2009年3月 (3)
2009年2月 (6)
2008年12月 (8)
2008年11月 (3)
文章分类
(12)
J2se(3)
(rss)
Spring(8)
(rss)
Stu-notes(1)
(rss)
文章档案
(17)
2013年4月 (2)
2010年8月 (1)
2009年2月 (12)
2008年10月 (2)
搜索
积分与排名
积分 - 249961
排名 - 227
最新评论
1. re: Hibernate session 获取方式浅谈[未登录]
总结的到位,很值得学习!
--111
2. re: [转]java截取字符串,截串,substring和split,分割字母和数字,正则缝隙
ddd
--lukes
3. 将字符串-uadmin-padmin1208@192.168.0.222:/home/admin/zrl/java/rmi/activation分割成admin,admin1208,192.168.0.222,/home/admin/zrl/java/rmi/activation[未登录]
请帮忙
--美美
4. re: [转]Statement和PreparedStatement批量更新
对我的帮助真是太大了
--请问
5. re: [转]JDBC中Statement与PreparedStatement的区别
非常好的总结!顶
--naomi
评论排行榜
1. Hibernate session 获取方式浅谈(3)
2. [转]JDBC中Statement与PreparedStatement的区别(2)
3. [转]java截取字符串,截串,substring和split,分割字母和数字,正则缝隙(2)
4. [转]程序员职业规划(2)
5. [转]JDK5新特性汇总(与1.4对照)(2)
Powered By:
博客园
模板提供
:
沪江博客