- 浏览: 1336411 次
- 性别:
- 来自: 成都
文章分类
- 全部博客 (471)
- 原创文章 (4)
- Database (84)
- J2SE (63)
- Web (26)
- Javascript (30)
- Lucene (11)
- os (13)
- 算法 (8)
- Webservice (1)
- Open projects (18)
- Hibernate (18)
- Spring (15)
- Css (2)
- J2ee (2)
- 综合技术 (18)
- 安全管理 (13)
- PatternsInJava (27)
- NIO (5)
- Ibatis (2)
- 书籍收藏 (1)
- quartz (7)
- 并发编程 (15)
- oracle问题 (2)
- ios (60)
- coco2d-iphone (3)
- C++ (6)
- Zookeeper (2)
- golang (4)
- animation (2)
- android (1)
最新评论
-
dandingge123:
【引用】限制UITextField输入长度的方法 -
qja:
...
对List顺序,逆序,随机排列实例代码 -
安静听歌:
现在在搞这个,,,,,哎~头都大了,,,又freemarker ...
通用大型网站页面静态化解决方案(一) -
springdata-jpa:
java quartz定时任务demo教程源代码下载,地址:h ...
Quartz 配置参考 -
马清天:
[b][/b][list][*]引用[u][/u][/list ...
通用大型网站页面静态化解决方案(一)
来看看实现代理的两种方式:Static Proxy与Dynamic Proxy。严格来说这是属于模式的实现方式,不过藉由实例可以更了解Proxy模式的应用。
先来看个例子,这个例子是记录(log)动作,程式中很常需要为某些动作或事件作下记录,以便在事后检视或是作为除错时的资讯,一个最简单的例子如下:
- HelloSpeaker.java
import java.util.logging.*; public class HelloSpeaker { private Logger logger = Logger.getLogger(this.getClass().getName()); public void hello(String name) { logger.log(Level.INFO, "hello method starts...."); System.out.println("Hello, " + name); logger.log(Level.INFO, "hello method ends...."); } }
HelloSpeaker在执行hello()方法时,您希望能记录该方法已经执行及结束,最简单的作法就是如上在执行的前后加上记录动作,然而 Logger介入了HelloSpeaker中,记录这个动作并不属于HelloSpeaker,这使得HelloSpeaker增加了非业务上需要的逻辑在当中。
想想如果程式中这种记录的动作到处都有需求,上面这种写法势必造成必须复制记录动作的程式码,使得维护记录动作的困难度加大。如果不只有记录动作,有一些非物件本身职责的相关动作也混入了物件之中(例如权限检查、事务管理等等),会使得物件的负担更形加重,甚至混淆了物件的职责,物件本身的职责所占的程式码,或许远小于这些与物件职责不相关动作的程式码。
怎么办,用下面的方法或许好一些,先定义一个介面,然后实作该介面:
- IHello.java
public interface IHello { public void hello(String name); }
- HelloSpeaker.java
public class HelloSpeaker implements IHello { public void hello(String name) { System.out.println("Hello, " + name); } }
接下来实作一个代理物件HelloProxy:
- HelloProxy.java
import java.util.logging.*; public class HelloProxy implements IHello { private Logger logger = Logger.getLogger(this.getClass().getName()); private IHello helloObject; public HelloProxy(IHello helloObject) { this.helloObject = helloObject; } public void hello(String name) { logger.log(Level.INFO, "hello method starts...."); helloObject.hello(name); logger.log(Level.INFO, "hello method ends...."); } }
执行时可以如此:
helloProxy.hello("Justin");
代理物件HelloProxy将代理真正的HelloSpeaker来执行hello(),并在其前后加上记录的动作,这使得 HelloSpeaker在撰写时不必介入记录动作,HelloSpeaker可以专心于它的职责。
这是Static Proxy的基本范例,然而如您所看到的,代理物件的一个介面只服务于一种类型的物件,而且如果要代理的方法很多,势必要为每个方法进行代理, Static Proxy在程式规模稍大时就必定无法胜任。
Java在JDK 1.3之后加入协助开发Dynamic Proxy功能的类别,我们不必为特定物件与方法撰写特定的代理,使用Dynamic Proxy,可以使得一个handler服务于各个物件,首先,一个handler必须实现 java.lang.reflect.InvocationHandler:
- LogHandler.java
import java.util.logging.*; import java.lang.reflect.*; public class LogHandler implements InvocationHandler { private Logger logger = Logger.getLogger(this.getClass().getName()); private Object delegate; public Object bind(Object delegate) { this.delegate = delegate; return Proxy.newProxyInstance( delegate.getClass().getClassLoader(), delegate.getClass().getInterfaces(), this); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; try { logger.log(Level.INFO, "method starts..." + method); result = method.invoke(delegate, args); logger.log(Level.INFO, "method ends..." + method); } catch (Exception e){ logger.log(Level.INFO, e.toString()); } return result; } }
InvocationHandler的invoke()方法会传入被代理物件的方法名称与执行参数实际上要执行的方法交由method.invoke (),并在其前后加上记录动作,method.invoke()传回的物件是实际方法执行过后的回传结果。
Dynamic Proxy必须宣告介面,实作该介面,例如:
- IHello.java
public interface IHello { public void hello(String name); }
- HelloSpeaker.java
public class HelloSpeaker implements IHello { public void hello(String name) { System.out.println("Hello, " + name); } }
java.lang.reflect.Proxy的newProxyInstance()依要代理的物件、介面与handler产生一个代理物件,我们可以使用下面的方法来执行程式:
IHello helloProxy = (IHello) logHandler.bind(
new HelloSpeaker());
helloProxy.hello("Justin");
LogHandler不在服务于特定物件与介面,而HelloSpeaker也不用插入任何有关于记录的动作,它不用意识到记录动作的存在。
上文写的动态代理没有理解真正的代理,特指的是一个抽象类或者接口去实现代理。
接口
package com.ijo.proxy;
public interface IHello {
void sayHello(String name);
}
实现类
package com.ijo.proxy;
public class EnglishSay implements IHello {
public void sayHello(String name) {
System.out.println(name + " say hello word!!!");
}
}
代理类
package com.ijo.proxy.dynamic;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import com.ijo.proxy.EnglishSay;
import com.ijo.proxy.IHello;
public class StudyTest implements InvocationHandler {
private IHello delegate;
public Object bind(IHello delegate) {
this.delegate = delegate;
return Proxy.newProxyInstance(delegate.getClass().getClassLoader(),
delegate.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] objs)
throws Throwable {
Object result = null;
System.out.println("this is say begin");
result = method.invoke(delegate, objs);
System.out.println("this is say end");
return result;
}
public static void main(String[] args) {
StudyTest studyTest = new StudyTest();
IHello hello = (IHello) studyTest.bind(new EnglishSay());
hello.sayHello("chinaxxren ");
}
}
结果:
this is say begin
chinaxxren say hello word!!!
this is say end
发表评论
-
Java 事件传送技术
2010-12-20 14:16 1485developerWorks 中国 ... -
Design Pattern: Mediator 模式
2010-11-13 23:31 1239Mediator的意思是中介者、调节者、传递物,顾名思义,这个 ... -
Design Pattern: Command 模式
2010-11-13 23:30 1098如果您写过Java的Swing视窗程式,您可能使用过Comma ... -
Design Pattern: Strategy 模式
2010-11-13 23:25 1285考虑您要设计一个更换各种符号的工具类TextCharChang ... -
Design Pattern: State 模式
2010-11-13 23:22 1043如果您不了解TCP的连线方式,在看 Gof 的书介绍State ... -
Design Pattern: Read-Write-Lock 模式
2010-11-10 23:58 1174如果有一个资料档有可能同时间会有许多客户端对它进行读取与写入的 ... -
Design Pattern: Producer Consumer 模式
2010-11-10 23:52 1310Producer Consumer模式与 Guar ... -
Design Pattern: Guarded Suspension 模式
2010-11-10 23:48 1131考虑这么一个伺服器,它可以处理来自多个客户端的服务请求(Req ... -
Design Pattern: Observer 模式
2010-11-10 23:33 1035Java深入到一定程度,就不可避免的碰到设计模式(design ... -
Design Pattern: Iterator 模式
2010-11-10 23:22 1085这个模式已经被整合入Java的Collection.在大多数场 ... -
Design Pattern: Interpreter 模式
2010-11-10 23:17 1268对于一个具有层次节点关系的问题来说,如果您要剖析每一个节点,您 ... -
Design Pattern: Command 模式
2010-11-10 23:08 1344Command定义n 将来自客户端的请求传入一个对象,无需了解 ... -
Design Pattern: Chain of Responsibility 模式
2010-11-10 23:00 1257其实Chain of Responsibility ... -
Design Pattern: Flyweight 模式
2010-11-10 22:48 1401Flyweight(享元)模式定义:避免大量拥有相同内容的小类 ... -
Design Pattern: Facade 模式
2010-11-10 22:42 1305Facade模式的定义: 为子系统中的一组接口提供一个一致的界 ... -
Design Pattern: Decorator 模式
2010-11-10 22:35 1342装饰模式:Decorator常被翻译成"装饰&quo ... -
Design Pattern: Bridge 模式
2010-11-10 22:24 1149Bridge模式定义 :将抽象 ... -
Design Pattern: Default Adapter 模式(二)
2010-11-10 22:16 1522适配器模式定义:将两个 ... -
Design Pattern: Default Adapter 模式
2010-11-10 22:07 1117在Java中如果要定义事件 ... -
Design Pattern: Singleton 模式
2010-11-10 22:06 1042Singleton的英文意义是独身,也就是只有一个人,应用在物 ...
相关推荐
本资源“DesignPattern::pencil:设计模式_java实现以及详解”提供了一套详细的学习材料,帮助开发者理解和应用设计模式。 该资源的作者是“养码青年-Style”,他通过这个项目记录了自己的设计模式学习过程。鼓励...
DesignPattern-master这个压缩包可能包含了一个关于设计模式的项目或者教程资源。 设计模式分为三类:创建型模式(Creational Patterns)、结构型模式(Structural Patterns)和行为型模式(Behavioral Patterns)...
"designPattern:设计模式相关代码实现"这个项目,显然提供了不同设计模式在Java语言中的实际应用示例。 在Java世界里,设计模式主要分为三大类:创建型模式、结构型模式和行为型模式。每种模式都针对特定的编程问题...
本资源"DesignPattern:设计模式.net源代码"提供了一套基于.NET实现的设计模式示例,旨在帮助程序员更好地理解和应用这些模式。 在"DesignPattern-master"这个压缩包中,你可能找到的文件结构和内容包括: 1. **...
这个名为"DesignPattern"的压缩包文件很可能包含了一个Java实现的各种设计模式的示例程序。 在这个"DesignPattern-master"目录中,我们可以期待找到一系列与设计模式相关的Java源代码文件(.java),每个文件或...
23种设计模式(Design Pattern)的C++实现范例,包括下面列出的各种模式,代码包含较详细注释。另外附上“设计模式迷你手册.chm”供参考。 注:项目在 VS2008 下使用。 创建型: 抽象工厂模式(Abstract Factory) 生成...
"DesignPattern:C#设计模式示例"这个资源很可能是包含多个C#实现的设计模式示例代码库。 设计模式通常分为三类:创建型、结构型和行为型。每种模式都解决了特定场景下的问题,并提供了良好的代码组织和扩展性。 ...
在本文中,我们将深入探讨设计模式的核心概念,并结合"Head First DesignPattern_src"中的源码,详细解析一些关键的设计模式。 1. 单例模式(Singleton): 单例模式确保一个类只有一个实例,并提供全局访问点。在...
5. 代理模式(Proxy Pattern): 代理模式为其他对象提供一种代理以控制对这个对象的访问。在C#中,可以使用接口或者继承来实现静态代理,或者使用.NET Framework的`System.Reflection.Emit`命名空间动态生成代理类...
本项目"designPattern:练习设计模式"提供了一个学习和实践各种设计模式的平台。 1. **单例模式**:确保一个类只有一个实例,并提供一个全局访问点。在Java中,单例模式通常通过双重检查锁定、静态内部类或枚举来...
设计模式是软件工程中的一种最佳实践,它是在特定情境下解决常见问题的经验总结。...在DesignPattern-master这个压缩包中,你可以找到关于这些模式的详细讲解和实例代码,为你的Java开发之旅提供宝贵的参考资料。
这个名为"DesignPattern:有关设计模式的一些演示"的项目,可能是为了帮助开发者理解和应用各种设计模式。 设计模式分为三大类:创建型、结构型和行为型。创建型模式关注对象的创建过程,如单例(Singleton)、工厂...
"Design*Pattern*Framework*4.5" 可能指的是一个基于 .NET Framework 4.5 的设计模式实现或教程集合。 设计模式是经验丰富的软件开发者的智慧结晶,它们被分为三类:创建型、结构型和行为型。创建型模式涉及对象的...
代理模式(Proxy)为其他对象提供一种代理以控制对这个对象的访问。在Java中,静态代理和动态代理(JDK Proxy和CGLIB)是常见的实现方式。 最后,还有建造者模式(Builder)用于分步骤构建复杂对象,隔离对象的构造...
这个名为"Design-pattern:设计模式"的压缩包可能包含了一个关于设计模式的学习资源,比如代码示例或者教程。 创建型设计模式是设计模式中的一个类别,主要关注对象的创建过程。这类模式包括工厂方法(Factory ...
在这个“DesignPattern”仓库中,可能包含了对各种设计模式的详细解释、示例和应用。 设计模式分为三大类:创建型、结构型和行为型模式。创建型模式主要关注对象的创建过程,如单例模式(Singleton)、工厂模式...
本资料包“JAVA 23种设计模式(全).Design Pattern_Java模式”涵盖了所有23种经典的GOF(GoF,Gang of Four)设计模式,旨在帮助开发者深入理解和应用这些模式。 首先,我们来看一下23种设计模式的分类: 1. **创建...
本教程的"designpattern-master"可能包含以上各种设计模式的实例代码和详细解释,帮助学习者通过实践掌握这些模式。在实际项目中,灵活运用这些设计模式可以提高代码质量,使项目更加健壮和易于维护。对于PHP开发者...
在"DesignPattern-master"这个压缩包中,可能包含了这些模式的Java实现示例,以及相关的解释和用法说明。通过学习和应用这些模式,开发者可以提高代码质量,降低维护成本,并提升软件系统的可扩展性。对于任何Java...