- 浏览: 500283 次
- 性别:
- 来自: 广州
文章分类
最新评论
-
来这里学java:
...
实战篇:设计自己的Annotation -
yushui2000:
突然想到一种方法,就是1、2、2、3、4、5作为5个球(类似彩 ...
一道算法题目,值得一看 -
wst0350:
理解力
实战篇:设计自己的Annotation -
yingzhor:
楼下的,你看看代码不就知道怎么验证了吗?这不是放在sessio ...
利用servlet生成简单的验证码 -
ming_7755:
妙用Commons良药<三>
大家都清楚Spring的AOP方面工作是很优秀,但是其内在的基础的东西,还是有一大部分不太了解的,其AOP大量用了ThreadLocal,这一个在前面已做了介绍了,还有一个比较重要的怎样用动态代理组装成AOP.
说到动态代理,有两种情况,第一种是有接口的情况下,你可以选择为jdk自带的动态代理的方式来编写程序,但你想要为一个实在的类编写动态代理的方式的话,这时候就必须选择一些开源的lib包啦.spring和hibernate选择了同样的CGlib包,具体表现在:Hibernate主要是利用cglib生成pojo的子类并override get方法来实现lazy loading机制,Spring则是利用cglib来实现动态代理。
接下来我们就来看看动态代理这两个情况是怎样实现的吧.其实通过demo是比较容易理解一样东西的.所以打算写一个简单的例子来表达我的意思,大家都知道JavaEye社区可以发新帖子,可以修改自己的帖子,所以我们定义下面的一个接口.
当然,有接口啦,我们自然而然的为它写一个实现的类,作为演示并没有实质性的代码的:
因为一般情况下,你发布帖子和编辑要处在事务范围之内(假设的),所以我们新写下面的一个功能类TransactionManager,想让在postTopic和editTopic方法前后分别调用下面的beginTransaction和endTransaction方法.
剩下的问题就是,我们用方式把TransactionManager里面的两个方法织入到JavaEyeForumImpl类里面方法的合适的位置,很简单地,我们只需要写一个处理的Handler类,如下:
在上面的类中的invoke方法中,"Object obj = method.invoke(target, args);"前后的语句指定调用前该前做,调用后该做什么.
接下来,就是写一个测试类啦
测试类,请仔细看 Proxy.newProxyInstance这一个方法的第二个参数必须指定target.getClass().getInterfaces()这一个接口后,动态代理才能起效. 这是为什么说平时我们说jdk 中的动态代理有时候比较麻烦,那是还要指定特定的接口的原因.
测试代码运行结果如下:
接下来我们来看看怎样用CGLib来生成动态代理,首先把TestDynamicProxy.java和TransactionHandler.java两个类删除掉,免得影响视线嘛,呵呵;然后再新建一个CglibProxy代理类.
然后,我们再写一个测试类如下:
测试的结果如下:
参考资料:
http://www.nirvanastudio.org/java/cglib-指南.html cglib 指南
http://www.moon-soft.com/doc/45039.htm Java-AOP编程入门
http://www.iteye.com/topic/98178 [深入了解Java ClassLoader、Bytecode 、ASM、cglib]
说到动态代理,有两种情况,第一种是有接口的情况下,你可以选择为jdk自带的动态代理的方式来编写程序,但你想要为一个实在的类编写动态代理的方式的话,这时候就必须选择一些开源的lib包啦.spring和hibernate选择了同样的CGlib包,具体表现在:Hibernate主要是利用cglib生成pojo的子类并override get方法来实现lazy loading机制,Spring则是利用cglib来实现动态代理。
接下来我们就来看看动态代理这两个情况是怎样实现的吧.其实通过demo是比较容易理解一样东西的.所以打算写一个简单的例子来表达我的意思,大家都知道JavaEye社区可以发新帖子,可以修改自己的帖子,所以我们定义下面的一个接口.
package lighter.iteye.com; public interface JavaEyeForum { void postTopic(int topicId); void editTopic(int topicId); }
当然,有接口啦,我们自然而然的为它写一个实现的类,作为演示并没有实质性的代码的:
package lighter.iteye.com; public class JavaEyeForumImpl implements JavaEyeForum { public void postTopic(int topicId) { System.out.println("发布帖子,帖子的ID号为:"+topicId); } public void editTopic(int topicId) { System.out.println("编辑帖子,帖子的ID号为:"+topicId); } }
因为一般情况下,你发布帖子和编辑要处在事务范围之内(假设的),所以我们新写下面的一个功能类TransactionManager,想让在postTopic和editTopic方法前后分别调用下面的beginTransaction和endTransaction方法.
package lighter.iteye.com; public class TransactionManager { public static void beginTransaction(String methodName){ System.out.println(methodName + "开始事务管理!"); } public static void endTransaction(String methodName){ System.out.println(methodName + "事务管理结束!\n"); } }
剩下的问题就是,我们用方式把TransactionManager里面的两个方法织入到JavaEyeForumImpl类里面方法的合适的位置,很简单地,我们只需要写一个处理的Handler类,如下:
package lighter.iteye.com; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class TransactionHandler implements InvocationHandler { private Object target; public TransactionHandler(Object target) { this.target = target; } public Object invoke(Object proxy, Method method, Object[] args)throws Throwable { TransactionManager.beginTransaction(method.getName()); Object obj = method.invoke(target, args); TransactionManager.endTransaction(method.getName()); return obj; } }
在上面的类中的invoke方法中,"Object obj = method.invoke(target, args);"前后的语句指定调用前该前做,调用后该做什么.
接下来,就是写一个测试类啦
package lighter.iteye.com; import java.lang.reflect.Proxy; public class TestDynamicProxy { public static void main(String[] args) { JavaEyeForum target = new JavaEyeForumImpl(); TransactionHandler handler = new TransactionHandler(target); JavaEyeForum proxy = (JavaEyeForum) Proxy.newProxyInstance(target .getClass().getClassLoader(),target.getClass().getInterfaces(), handler); proxy.postTopic(100); proxy.editTopic(999); } }
测试类,请仔细看 Proxy.newProxyInstance这一个方法的第二个参数必须指定target.getClass().getInterfaces()这一个接口后,动态代理才能起效. 这是为什么说平时我们说jdk 中的动态代理有时候比较麻烦,那是还要指定特定的接口的原因.
测试代码运行结果如下:
引用
postTopic 开始事务管理!
发布帖子,帖子的ID号为:100
postTopic事务管理结束!
editTopic 开始事务管理!
编辑帖子,帖子的ID号为:999
editTopic事务管理结束!
发布帖子,帖子的ID号为:100
postTopic事务管理结束!
editTopic 开始事务管理!
编辑帖子,帖子的ID号为:999
editTopic事务管理结束!
接下来我们来看看怎样用CGLib来生成动态代理,首先把TestDynamicProxy.java和TransactionHandler.java两个类删除掉,免得影响视线嘛,呵呵;然后再新建一个CglibProxy代理类.
package lighter.iteye.com; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; /** * net.sf.cglib.proxy.Enhancer和MethodInterceptor在CGLib中负责完成代理对象创建和方法截获处理, * 产生的是目标类的子类而不是通过接口来实现方法拦截的,Enhancer主要是用于构造动态代理子类来实现拦截,MethodInterceptor(扩展了 * Callback接口)主要用于实现around advice(AOP中的概念) */ public class CglibProxy implements MethodInterceptor { private Enhancer enhancer = new Enhancer(); public Object getProxy(Class clazz) { enhancer.setSuperclass(clazz); enhancer.setCallback(this); return enhancer.create(); } public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable { String methodName = obj.getClass().getName()+"."+method.getName(); TransactionManager.beginTransaction(methodName); Object result = proxy.invokeSuper(obj, args); TransactionManager.endTransaction(methodName); return result; } }
然后,我们再写一个测试类如下:
package lighter.iteye.com; public class TestCGLibProxy { public static void main(String[] args) { CglibProxy proxy = new CglibProxy(); JavaEyeForum forum = (JavaEyeForum)proxy.getProxy(JavaEyeForumImpl.class); forum.postTopic(999); forum.editTopic(999); } }
测试的结果如下:
引用
lighter.iteye.com.JavaEyeForumImpl$$EnhancerByCGLIB$$155ad1e9.postTopic 开始事务管理!
发布帖子,帖子的ID号为:999
lighter.iteye.com.JavaEyeForumImpl$$EnhancerByCGLIB$$155ad1e9.postTopic事务管理结束!
lighter.iteye.com.JavaEyeForumImpl$$EnhancerByCGLIB$$155ad1e9.editTopic 开始事务管理!
编辑帖子,帖子的ID号为:999
lighter.iteye.com.JavaEyeForumImpl$$EnhancerByCGLIB$$155ad1e9.editTopic事务管理结束!
发布帖子,帖子的ID号为:999
lighter.iteye.com.JavaEyeForumImpl$$EnhancerByCGLIB$$155ad1e9.postTopic事务管理结束!
lighter.iteye.com.JavaEyeForumImpl$$EnhancerByCGLIB$$155ad1e9.editTopic 开始事务管理!
编辑帖子,帖子的ID号为:999
lighter.iteye.com.JavaEyeForumImpl$$EnhancerByCGLIB$$155ad1e9.editTopic事务管理结束!
参考资料:
http://www.nirvanastudio.org/java/cglib-指南.html cglib 指南
http://www.moon-soft.com/doc/45039.htm Java-AOP编程入门
http://www.iteye.com/topic/98178 [深入了解Java ClassLoader、Bytecode 、ASM、cglib]
发表评论
-
读源码之旅 有意思的Integer类
2010-02-01 09:33 2185Integer类里面有如下一段 ... -
读源码之旅 java.io包
2010-01-28 16:11 2318对于下图,研究了一下常用的InputStream,ByteAr ... -
从自身体会谈一谈测试
2008-01-21 13:05 1977论坛上关于测试的帖子 ... -
The Contract for Equality[java]
2008-01-14 20:43 1570As we Know,The Java API documen ... -
来改善你的switch语句
2007-12-26 13:10 2808善用多态来改善你的switch语句 下面举的 ... -
url传递中文参数笔录
2007-12-21 19:35 4272url传递中文参数笔录 ... -
小心给servlet忽悠了
2007-12-05 18:53 2306你真的会写线程安全的s ... -
ThreadLocal浅解
2007-12-01 13:16 2266如果有看到spring的一些源码的同学都知道,Threa ... -
体会Observer/Observable模式
2007-11-23 19:20 3163在现在的项目中,后台有一块程序感觉用Observer/Obse ... -
Java 5.0多线程编程学习资料笔录
2007-11-23 13:33 3836对于Java 5.0多线程编程的学习,可以参考一下网上的下面的 ... -
关于ClassLoader工作机制小记
2007-11-06 23:06 2320类装载器就是寻找类或接口字节文件进行解析并构造JVM内部对象表 ... -
web应用程序开发须注意私自启动线程的问题
2007-11-04 01:25 3227web应用程序开发注意私自启动线程的问题 我们知道静态变量是 ... -
interrupt方法点滴记录
2007-10-25 21:02 28241、sleep方法与interrupt方法 假如线程A像下 ... -
wait方法是在什么时候结束
2007-10-23 11:07 2910wait方法是在什么时候结束 1、当notify方法执行时 ... -
synchronized 笔记
2007-10-18 11:04 2905synchronized 笔记 1、synchronized ... -
该用notify 方法还是notifyAll方法
2007-10-18 10:15 2284选择notify的话,因为要唤醒的线程比较少,程序处理速度当然 ... -
有趣而简单的两段代码
2007-09-04 20:40 2204假如你想写一个小程序,保证字符串首尾两个字符是一样的,你可以如 ... -
正则表达式[浅例学习]
2007-07-17 16:19 2113举下面一段代码: public\\s+void\\s+test ... -
熟悉一下几个常用的eclipse快捷键
2007-07-16 13:03 1881在论坛里看到一个帖子,是Godlikeme在这一个帖子写的 h ... -
线程间通信一小例学习
2007-06-16 13:41 3431wait:告诉线程放弃监视器并进入睡眠状态,直到其他线程进入同 ...
相关推荐
Java的核心理念是“简单、面向对象、分布式、健壮、安全、性能高效、可移植、动态”。 【JDK(Java Development Kit)】 JDK是Java开发工具包,它是学习和开发Java程序的基础。它包含了Java编译器(javac)、Java...
市场产品现状 侦查询问笔录 产品现状 笔录的历史记录缺乏有效利用, 区域内的笔录不能共享 笔录生成缺乏法律库、经验库实时指导 笔录信息不能及时与公安业务 实时对接缺乏实战性 笔录记录时,人工打字效率慢 智能...
Java是一种广泛使用的高级编程语言,由Sun Microsystems(后被Oracle公司收购)于1995年推出。它的设计目标是成为“一次编写,到处运行”的平台无关性语言,这得益于Java虚拟机(JVM)的存在。Java的核心理念是面向...
破产清算组询问笔录.pdf 破产清算组询问笔录是一种企业非诉文书,用于记录破产清算组与相关人员或单位之间的询问过程。该文书类型中包含了询问的基本信息,如时间、地点、被询问人、询问人、询问主题、内容、询问...
Java标准IO流编程是Java平台基础且至关重要的部分,它提供了对输入输出数据进行操作的能力。I/O(Input/Output)涉及从外部源(如文件、网络连接等)读取数据,以及向这些源写入数据。在Java中,IO流被设计成一个流...
律师庭审笔录的内容包括审讯时间、地点、记录人、审判人员、书记员、原告、代理人、被告、代理人、第三人、代理人、案由等信息。 1. 审讯时间:指律师庭审笔录的日期和时间。 2. 地点:指律师庭审笔录的所在地点。 ...
标题中提到的“现场勘验检查笔录”是一种正式的法律文件,它详细记录了警方或调查人员在犯罪现场所进行的勘查和检查活动。在司法程序中,现场勘验检查笔录作为证据的一部分,对案件的调查和审理起着至关重要的作用。...
尽职调查访谈笔录
### 律师庭审笔录知识点解析 #### 一、文件基本信息 - **文件名**:“律师庭审笔录(模板).pdf” - **描述**:该文档为律师在庭审过程中记录的标准化模板,用于指导律师如何准确、规范地记录庭审过程中的各项细节。 ...
Java在线编辑保存Word文件是一项常见的需求,特别是在Web应用中,用户可能需要在浏览器环境中直接对文档进行编辑操作。PageOffice是一款强大的Java组件,它能够帮助开发者实现这一功能,特别是其V4.4版本,提供了跨...
此外,指南还涉及了其他类型的笔录制作,如讯问笔录、询问笔录、现场勘查笔录、搜查笔录、人身检查笔录、辨认笔录和侦查实验笔录。这些笔录各有侧重,如讯问笔录针对嫌疑人的审讯,询问笔录适用于证人证言的记录,...
"强大的电子笔录办公软件"就是这样一款工具,它专门设计用于提升笔录工作的质量和速度,为用户提供了前所未有的便捷体验。这款软件集成了多种功能,旨在优化办公流程,减少手动输入的时间,提高数据的准确性,确保...
笔录软件好用
安全生产事故调查询问笔录制作要求示范文本.pdf
厦门市公安局开发运用的公安笔录制作管理信息系统。
信访接待谈话笔录.pdf
律师调查笔录范例.doc
《如何有效利用“工作会议笔录PPT模板”提升工作效率》 在现代企业环境中,会议是信息交流、决策制定的重要场所,而会议笔录则是确保会议成果得以有效传达和执行的关键工具。一个精心设计的会议笔录PPT模板,能够...
标题中的“调查笔录模板(单位通用).rar”暗示了这是一个关于调查笔录的文档集合,通常用于组织或企业内部进行各类调查时记录信息。在教育领域,这样的模板可能被用作教学材料,帮助学生理解如何正确进行调查工作,...