JAVA中的委托.docx

上传人:b****2 文档编号:2442346 上传时间:2023-05-03 格式:DOCX 页数:14 大小:18.49KB
下载 相关 举报
JAVA中的委托.docx_第1页
第1页 / 共14页
JAVA中的委托.docx_第2页
第2页 / 共14页
JAVA中的委托.docx_第3页
第3页 / 共14页
JAVA中的委托.docx_第4页
第4页 / 共14页
JAVA中的委托.docx_第5页
第5页 / 共14页
JAVA中的委托.docx_第6页
第6页 / 共14页
JAVA中的委托.docx_第7页
第7页 / 共14页
JAVA中的委托.docx_第8页
第8页 / 共14页
JAVA中的委托.docx_第9页
第9页 / 共14页
JAVA中的委托.docx_第10页
第10页 / 共14页
JAVA中的委托.docx_第11页
第11页 / 共14页
JAVA中的委托.docx_第12页
第12页 / 共14页
JAVA中的委托.docx_第13页
第13页 / 共14页
JAVA中的委托.docx_第14页
第14页 / 共14页
亲,该文档总共14页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

JAVA中的委托.docx

《JAVA中的委托.docx》由会员分享,可在线阅读,更多相关《JAVA中的委托.docx(14页珍藏版)》请在冰点文库上搜索。

JAVA中的委托.docx

JAVA中的委托

JAVA的动态代理

代理模式

代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。

代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。

按照代理的创建时期,代理类可以分为两种。

静态代理:

由程序员创建或特定工具自动生成源代码,再对其编译。

在程序运行前,代理类的.class文件就已经存在了。

动态代理:

在程序运行时,运用反射机制动态创建而成。

首先看一下静态代理:

1、Count.java

Java代码

1packagenet.battier.dao;

2

3/**

4*定义一个账户接口

5*

6*@authorAdministrator

7*

8*/

9publicinterfaceCount{

10//查看账户方法

11publicvoidqueryCount();

12

13//修改账户方法

14publicvoidupdateCount();

15

16}

2、CountImpl.java

Java代码

17packagenet.battier.dao.impl;

18

19importnet.battier.dao.Count;

20

21/**

22*委托类(包含业务逻辑)

23*

24*@authorAdministrator

25*

26*/

27publicclassCountImplimplementsCount{

28

29@Override

30publicvoidqueryCount(){

31System.out.println("查看账户方法...");

32

33}

34

35@Override

36publicvoidupdateCount(){

37System.out.println("修改账户方法...");

38

39}

40

41}

42

43、CountProxy.java

44packagenet.battier.dao.impl;

45

46importnet.battier.dao.Count;

47

48/**

49*这是一个代理类(增强CountImpl实现类)

50*

51*@authorAdministrator

52*

53*/

54publicclassCountProxyimplementsCount{

55privateCountImplcountImpl;

56

57/**

58*覆盖默认构造器

59*

60*@paramcountImpl

61*/

62publicCountProxy(CountImplcountImpl){

63this.countImpl=countImpl;

64}

65

66@Override

67publicvoidqueryCount(){

68System.out.println("事务处理之前");

69//调用委托类的方法;

70countImpl.queryCount();

71System.out.println("事务处理之后");

72}

73

74@Override

75publicvoidupdateCount(){

76System.out.println("事务处理之前");

77//调用委托类的方法;

78countImpl.updateCount();

79System.out.println("事务处理之后");

80

81}

82

83}

3、TestCount.java

Java代码

84packagenet.battier.test;

85

86importnet.battier.dao.impl.CountImpl;

87importnet.battier.dao.impl.CountProxy;

88

89/**

90*测试Count类

91*

92*@authorAdministrator

93*

94*/

95publicclassTestCount{

96publicstaticvoidmain(String[]args){

97CountImplcountImpl=newCountImpl();

98CountProxycountProxy=newCountProxy(countImpl);

99countProxy.updateCount();

100countProxy.queryCount();

101

102}

103}

观察代码可以发现每一个代理类只能为一个接口服务,这样一来程序开发中必然会产生过多的代理,而且,所有的代理操作除了调用的方法不一样之外,其他的操作都一样,则此时肯定是重复代码。

解决这一问题最好的做法是可以通过一个代理类完成全部的代理功能,那么此时就必须使用动态代理完成。

再来看一下动态代理:

JDK动态代理中包含一个类和一个接口:

InvocationHandler接口:

publicinterfaceInvocationHandler{

publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable;

}

参数说明:

Objectproxy:

指被代理的对象。

Methodmethod:

要调用的方法

Object[]args:

方法调用时所需要的参数

可以将InvocationHandler接口的子类想象成一个代理的最终操作类,替换掉ProxySubject。

Proxy类:

Proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类,此类提供了如下的操作方法:

publicstaticObjectnewProxyInstance(ClassLoaderloader,Class

>[]interfaces,

InvocationHandlerh)

throwsIllegalArgumentException

参数说明:

ClassLoaderloader:

类加载器

Class

>[]interfaces:

得到全部的接口

InvocationHandlerh:

得到InvocationHandler接口的子类实例

Ps:

类加载器

在Proxy类中的newProxyInstance()方法中需要一个ClassLoader类的实例,ClassLoader实际上对应的是类加载器,在Java中主要有一下三种类加载器;

BooststrapClassLoader:

此加载器采用C++编写,一般开发中是看不到的;

ExtendsionClassLoader:

用来进行扩展类的加载,一般对应的是jre\lib\ext目录中的类;

AppClassLoader:

(默认)加载classpath指定的类,是最常使用的是一种加载器。

动态代理

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

动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java反射机制可以生成任意类型的动态代理类。

java.lang.reflect包中的Proxy类和InvocationHandler接口提供了生成动态代理类的能力。

动态代理示例:

1、BookFacade.java

Java代码

104packagenet.battier.dao;

105

106publicinterfaceBookFacade{

107publicvoidaddBook();

108}

2、BookFacadeImpl.java

Java代码

109packagenet.battier.dao.impl;

110

111importnet.battier.dao.BookFacade;

112

113publicclassBookFacadeImplimplementsBookFacade{

114

115@Override

116publicvoidaddBook(){

117System.out.println("增加图书方法。

");

118}

119

120}

121

122、BookFacadeProxy.java

123

124packagenet.battier.proxy;

125

126importjava.lang.reflect.InvocationHandler;

127importjava.lang.reflect.Method;

128importjava.lang.reflect.Proxy;

129

130/**

131*JDK动态代理代理类

132*

133*@authorstudent

134*

135*/

136publicclassBookFacadeProxyimplementsInvocationHandler{

137privateObjecttarget;

138/**

139*绑定委托对象并返回一个代理类

140*@paramtarget

141*@return

142*/

143publicObjectbind(Objecttarget){

144this.target=target;

145//取得代理对象

146returnProxy.newProxyInstance(target.getClass().getClassLoader(),

147target.getClass().getInterfaces(),this);//要绑定接口(这是一个缺陷,cglib弥补了这一缺陷)

148}

149

150@Override

151/**

152*调用方法

153*/

154publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)

155throwsThrowable{

156Objectresult=null;

157System.out.println("事物开始");

158//执行方法

159result=method.invoke(target,args);

160System.out.println("事物结束");

161returnresult;

162}

163

164}

3、TestProxy.java

Java代码

165packagenet.battier.test;

166

167importnet.battier.dao.BookFacade;

168importnet.battier.dao.impl.BookFacadeImpl;

169importnet.battier.proxy.BookFacadeProxy;

170

171publicclassTestProxy{

172

173publicstaticvoidmain(String[]args){

174BookFacadeProxyproxy=newBookFacadeProxy();

175BookFacadebookProxy=(BookFacade)proxy.bind(newBookFacadeImpl());

176bookProxy.addBook();

177}

178

179}

但是,JDK的动态代理依靠接口实现,如果有些类并没有实现接口,则不能使用JDK代理,这就要使用cglib动态代理了。

Cglib动态代理

JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。

示例

1、BookFacadeCglib.java

Java代码

180packagenet.battier.dao;

181

182publicinterfaceBookFacade{

183publicvoidaddBook();

184}

2、BookCadeImpl1.java

Java代码

185packagenet.battier.dao.impl;

186

187/**

188*这个是没有实现接口的实现类

189*

190*@authorstudent

191*

192*/

193publicclassBookFacadeImpl1{

194publicvoidaddBook(){

195System.out.println("增加图书的普通方法...");

196}

197}

3、BookFacadeProxy.java

Java代码

198packagenet.battier.proxy;

199

200importjava.lang.reflect.Method;

201

202importnet.sf.cglib.proxy.Enhancer;

203importnet.sf.cglib.proxy.MethodInterceptor;

204importnet.sf.cglib.proxy.MethodProxy;

205

206/**

207*使用cglib动态代理

208*

209*@authorstudent

210*

211*/

212publicclassBookFacadeCglibimplementsMethodInterceptor{

213privateObjecttarget;

214

215/**

216*创建代理对象

217*

218*@paramtarget

219*@return

220*/

221publicObjectgetInstance(Objecttarget){

222this.target=target;

223Enhancerenhancer=newEnhancer();

224enhancer.setSuperclass(this.target.getClass());

225//回调方法

226enhancer.setCallback(this);

227//创建代理对象

228returnenhancer.create();

229}

230

231@Override

232//回调方法

233publicObjectintercept(Objectobj,Methodmethod,Object[]args,

234MethodProxyproxy)throwsThrowable{

235System.out.println("事物开始");

236proxy.invokeSuper(obj,args);

237System.out.println("事物结束");

238returnnull;

239

240

241}

242

243}

4、TestCglib.java

Java代码

244packagenet.battier.test;

245

246importnet.battier.dao.impl.BookFacadeImpl1;

247importnet.battier.proxy.BookFacadeCglib;

248

249publicclassTestCglib{

250

251publicstaticvoidmain(String[]args){

252BookFacadeCglibcglib=newBookFacadeCglib();

253BookFacadeImpl1bookCglib=(BookFacadeImpl1)cglib.getInstance(newBookFacadeImpl1());

254bookCglib.addBook();

255}

256}

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 求职职场 > 社交礼仪

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2