- 浏览: 504607 次
- 性别:
- 来自: 广州
-
文章分类
最新评论
-
来这里学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 2248Integer类里面有如下一段 ... -
读源码之旅 java.io包
2010-01-28 16:11 2350对于下图,研究了一下常用的InputStream,ByteAr ... -
从自身体会谈一谈测试
2008-01-21 13:05 2011论坛上关于测试的帖子 ... -
The Contract for Equality[java]
2008-01-14 20:43 1615As we Know,The Java API documen ... -
来改善你的switch语句
2007-12-26 13:10 2843善用多态来改善你的switch语句 下面举的 ... -
url传递中文参数笔录
2007-12-21 19:35 4317url传递中文参数笔录 ... -
小心给servlet忽悠了
2007-12-05 18:53 2346你真的会写线程安全的s ... -
ThreadLocal浅解
2007-12-01 13:16 2318如果有看到spring的一些源码的同学都知道,Threa ... -
体会Observer/Observable模式
2007-11-23 19:20 3188在现在的项目中,后台有一块程序感觉用Observer/Obse ... -
Java 5.0多线程编程学习资料笔录
2007-11-23 13:33 3858对于Java 5.0多线程编程的学习,可以参考一下网上的下面的 ... -
关于ClassLoader工作机制小记
2007-11-06 23:06 2367类装载器就是寻找类或接口字节文件进行解析并构造JVM内部对象表 ... -
web应用程序开发须注意私自启动线程的问题
2007-11-04 01:25 3260web应用程序开发注意私自启动线程的问题 我们知道静态变量是 ... -
interrupt方法点滴记录
2007-10-25 21:02 28711、sleep方法与interrupt方法 假如线程A像下 ... -
wait方法是在什么时候结束
2007-10-23 11:07 2949wait方法是在什么时候结束 1、当notify方法执行时 ... -
synchronized 笔记
2007-10-18 11:04 2953synchronized 笔记 1、synchronized ... -
该用notify 方法还是notifyAll方法
2007-10-18 10:15 2321选择notify的话,因为要唤醒的线程比较少,程序处理速度当然 ... -
有趣而简单的两段代码
2007-09-04 20:40 2244假如你想写一个小程序,保证字符串首尾两个字符是一样的,你可以如 ... -
正则表达式[浅例学习]
2007-07-17 16:19 2144举下面一段代码: public\\s+void\\s+test ... -
熟悉一下几个常用的eclipse快捷键
2007-07-16 13:03 1912在论坛里看到一个帖子,是Godlikeme在这一个帖子写的 h ... -
线程间通信一小例学习
2007-06-16 13:41 3465wait:告诉线程放弃监视器并进入睡眠状态,直到其他线程进入同 ...
相关推荐
- **基于代理的AOP**:适用于接口的实现类。 - **基于类的AOP**:可以应用于任何Java类,无论是否实现了接口。 ##### 2.3 Spring Web Spring Web模块为Web应用程序提供了基础支持。它包括以下两个主要子模块: - ...
例如,研究AOP的代理机制可以让人明白如何在运行时动态地织入切面代码,而DI的实现则能揭示对象间的依赖是如何被自动管理的。 “工具”标签可能暗示了Spring与其他开发工具的集成,如数据库连接池(如HikariCP)、...
scratch少儿编程逻辑思维游戏源码-工厂逃生.zip
房地产 -辉盛阁项目介绍.pptx
少儿编程scratch项目源代码文件案例素材-新拉力赛.zip
scratch少儿编程逻辑思维游戏源码-混乱弹球.zip
scratch少儿编程逻辑思维游戏源码-过马路.zip
少儿编程scratch项目源代码文件案例素材-侠盗地牢冒险.zip
少儿编程scratch项目源代码文件案例素材-我的领土.zip
scratch少儿编程逻辑思维游戏源码-机器人闯关.zip
少儿编程scratch项目源代码文件案例素材-天空中的英雄.zip
少儿编程scratch项目源代码文件案例素材-突击尖峰.zip
“即刻青旅”前景广阔,随着青年旅舍行业快速发展,2030年市场规模预计达650亿。创作旨在为年轻旅行者打造专属平台,填补国内专门青旅预定空白。融合微信小程序、Spring Boot等技术,实现青旅查询预定、订单管理、活动职位查看及社区分享等功能。 后端框架: 基于Java的SpringBoot快速开发框架 借助Mybatis-plus构建ORM模型进行数据库操作 第三方API:高德地图、腾讯地图
少儿编程scratch项目源代码文件案例素材-像素猫3.zip
内容概要:本文是一份详细的10bit 50MHz SAR ADC学习指南,旨在帮助新手掌握从基础理论到实际电路设计的全过程。文中详细介绍了Cadence仿真工具的应用以及SMIC 40nm工艺库的具体使用方法。重点讲解了栅压自举开关、CDAC(电荷再分配模数转换器)、比较器和SAR逻辑等核心模块的设计原理和技术要点。此外,还提供了测试电路的构建方法及其性能评估手段,如INL/DNL曲线绘制。最后提到了更高性能TI ADC的扩展接口,为后续深入研究打下基础。 适合人群:对模拟集成电路设计感兴趣的电子工程专业学生或刚入行的研发人员。 使用场景及目标:适用于希望深入了解SAR ADC架构、提高自身硬件设计能力的学习者;目标是在实践中掌握关键技术和优化技巧,能够独立完成类似项目的开发。 其他说明:文章不仅提供理论知识,还包括大量实用的操作提示和常见错误避免建议,有助于读者快速上手并减少试错成本。
scratch少儿编程逻辑思维游戏源码-防空火力 3D.zip
智慧消防安全与应急管理是现代城市安全管理的重要组成部分,随着城市化进程的加速,传统消防安全管理面临着诸多挑战,如消防安全责任制度落实不到位、消防设施日常管理不足、消防警力不足等。这些问题不仅制约了消防安全管理水平的提升,也给城市的安全运行带来了潜在风险。然而,物联网和智慧城市技术的快速发展为解决这些问题提供了新的思路和方法。智慧消防作为物联网和智慧城市技术结合的创新产物,正在成为社会消防安全管理的新趋势。 智慧消防的核心在于通过技术创新实现消防安全管理的智能化和自动化。其主要应用包括物联网消防安全监管平台、城市消防远程监控系统、智慧消防平台等,这些系统利用先进的技术手段,如GPS、GSM、GIS等,实现了对消防设施的实时监控、智能巡检和精准定位。例如,单兵定位方案通过信标点定位和微惯导加蓝牙辅助定位技术,能够精确掌握消防人员的位置信息,从而提高救援效率和安全性。智慧消防不仅提升了消防设施的管理质量,还优化了社会消防安全管理资源的配置,降低了管理成本。此外,智慧消防的应用还弥补了传统消防安全管理中数据处理方式落后、值班制度执行不彻底等问题,赋予了建筑消防设施智能化、自动化的能力。 尽管智慧消防技术在社会消防安全管理工作中的应用已经展现出巨大的潜力和优势,但目前仍处于实践探索阶段。相关职能部门和研究企业需要加大研究开发力度,进一步完善系统的功能与实效性。智慧消防的发展既面临风险,也充满机遇。当前,社会消防安全管理工作中仍存在制度执行不彻底、消防设施日常维护不到位等问题,而智慧消防理念与技术的应用可以有效弥补这些弊端,提高消防安全管理的自动化与智能化水平。随着智慧城市理念的不断发展和实践,智慧消防将成为推动社会消防安全管理工作与城市化进程同步发展的关键力量。
scratch少儿编程逻辑思维游戏源码-节奏空间.zip
scratch少儿编程逻辑思维游戏源码-黑白色.zip
scratch少儿编程逻辑思维游戏源码-简单射击游戏.zip