- 浏览: 41003 次
- 性别:
- 来自: 北京
最新评论
最近研究了一下javassist框架,目前我对它的理解是它是一个动态创建类的框架。作为自己的学习的阶段成果使用它模拟了一个jdk动态代理的实现,在这里和大家分享一下。其实这反射的编程比想象中的麻烦一点的,期间遇到很多不好解决的问题放到javassist就不能执行,还好自己还是坚持完成了。如果我的实现方式有可优化或者漏洞欢迎大家指出。
主要实现类
MyProxy:提供一个静态方法创建代理对象,主要代码都在这里。整理思路是使用它动态的创建一个类然后使用MyInvocationHandler的实现调用业务接口实现类的具体方法,这样就完成了动态代理一个类的基本操作;
MyInvocationHandler:提供一个动态代理的接口供使用者使用,比较简单;
MyProxy
MyInvocationHandler
测试代码:
业务接口类IEcho
业务接口实现类EchoEn
代理模式接口实现类:TestInvocationHandler
测试代码
输出结果:
主要实现类
MyProxy:提供一个静态方法创建代理对象,主要代码都在这里。整理思路是使用它动态的创建一个类然后使用MyInvocationHandler的实现调用业务接口实现类的具体方法,这样就完成了动态代理一个类的基本操作;
MyInvocationHandler:提供一个动态代理的接口供使用者使用,比较简单;
MyProxy
package qhy.demo.javassist.myDynamicProxy; import java.lang.reflect.Modifier; import javassist.ClassPool; import javassist.CtClass; import javassist.CtField; import javassist.CtField.Initializer; import javassist.CtMethod; public class MyProxy { private static int proxyIndex = 1; private static String PROXY_SUFFIX="_$Proxy_"; //代理类的名称 /** * * Description: 创建代理对象. <br/> * @param interfaceClass 接口定义 * @param implClass 实现类 * @param invocationClass 代理类 * @return * @throws Exception */ public static <T> T newProxyInstance(Class<T> interfaceClass, Class<? extends T> implClass, Class<? extends MyInvocationHandler> invocationClass) throws Exception { String interfaceName = interfaceClass.getName(); //业务接口 String implClassName = implClass.getName();//业务实现类,被代理的对象 String invocationImplClassName = invocationClass.getName(); //代理模式接口实现类 //开始生成代理类实例 String proxyClassName = interfaceName + PROXY_SUFFIX + proxyIndex++; ClassPool cp = ClassPool.getDefault(); CtClass proxyImplClass = cp.makeClass(proxyClassName); //1、设置实现类的 接口 CtClass interfaceCtClass = cp.getCtClass(interfaceName); proxyImplClass.addInterface(interfaceCtClass); CtMethod[] interfaceCtMethods = interfaceCtClass.getDeclaredMethods(); if(interfaceCtMethods !=null && interfaceCtMethods.length > 0){ //2、注入invocationHandler 属性 CtField newField = new CtField(cp.get(invocationImplClassName), "testInvoke", proxyImplClass); newField.setModifiers(Modifier.PRIVATE); proxyImplClass.addField(newField, Initializer.byExpr(" testInvoke = new "+invocationImplClassName+"();")); int i = 0; for (CtMethod ctMethod : interfaceCtMethods) { //3、循环创建接口的实现方法 //3.1、创建方法定义 String methodName = ctMethod.getName(); CtClass returnType = ctMethod.getReturnType(); CtClass[] paramTypes = ctMethod.getParameterTypes(); CtMethod newMethod = new CtMethod(returnType, methodName, paramTypes, proxyImplClass); newMethod.setModifiers(Modifier.PUBLIC); //3.1、创建方法体 StringBuffer body = new StringBuffer(); body.append("{"); //3.2、生成获取指定实现类方法的代码 String getMethodArg = generateImplGetMethodCode(methodName,implClassName,paramTypes); body.append("\n Object result = testInvoke.invoke(Class.forName(\""+implClassName+"\").newInstance(),"+getMethodArg+",$args);"); //3.3、生成获取指定实现类方法的代码 String returnCode = generateImplReturnCode(returnType,"result"); if(returnCode !=null && returnCode.trim().length()>5){ body.append(returnCode); } // body.append("\n return ("+returnType.getName()+")result;"); body.append("}"); newMethod.setBody(body.toString()); proxyImplClass.addMethod(newMethod); i++; } } Object obj = proxyImplClass.toClass().newInstance(); return (T)obj; } /** * Description:生成返回代码 . <br/> * @param returnType * @param string * @return */ private static String generateImplReturnCode(CtClass returnType, String returnVariableName) { String returnCode = null; if(returnType != CtClass.voidType){ if(returnType.isPrimitive()){ if(returnType == CtClass.intType){ returnCode = "\n return (("+Integer.class.getName()+")"+returnVariableName+").intValue();"; }else if(returnType == CtClass.byteType){ returnCode = "\n return (("+Byte.class.getName()+")"+returnVariableName+").byteValue();"; }else if(returnType == CtClass.booleanType){ returnCode = "\n return (("+Boolean.class.getName()+")"+returnVariableName+").booleanValue();"; }else if(returnType == CtClass.charType){ returnCode = "\n return (("+Character.class.getName()+")"+returnVariableName+").charValue();"; }else if(returnType == CtClass.doubleType){ returnCode = "\n return (("+Double.class.getName()+")"+returnVariableName+").doubleValue();"; }else if(returnType == CtClass.floatType){ returnCode = "\n return (("+Float.class.getName()+")"+returnVariableName+").floatValue();"; }else if(returnType == CtClass.longType){ returnCode = "\n return (("+Long.class.getName()+")"+returnVariableName+").longValue();"; }else if(returnType == CtClass.shortType){ returnCode = "\n return (("+Short.class.getName()+")"+returnVariableName+").shortValue();"; } }else{ returnCode = "\n return ("+returnType.getName()+") "+returnVariableName+";"; } } return returnCode; } /** * Description: 获取方法的代码指定实现方法的代码. <br/> * @param methodName * @param implClassName * @param paramTypes */ private static String generateImplGetMethodCode(String methodName, String implClassName, CtClass[] paramTypes) { //没用约束的方法这么定义获取方式 String getMethodArg="Class.forName(\""+implClassName+"\").getDeclaredMethod(\""+methodName+"\", null)"; if(paramTypes!=null && paramTypes.length>0){ StringBuffer sb = new StringBuffer("new Class[]{"); int paramLength = paramTypes.length; for (int j = 0; j < paramLength; j++) { String calssName = paramTypes[j].getName(); if(j == (paramLength-1)){ sb.append(calssName).append(".class"); }else{ sb.append(calssName).append(".class").append(","); } } sb.append("}"); getMethodArg = "Class.forName(\""+implClassName+"\").getDeclaredMethod(\""+methodName+"\","+sb.toString()+")"; } return getMethodArg; } }
MyInvocationHandler
package qhy.demo.javassist.myDynamicProxy; import java.lang.reflect.Method; public interface MyInvocationHandler { public Object invoke(Object proxy,Method method,Object[] args) throws Throwable; }
测试代码:
业务接口类IEcho
package qhy.demo.javassist.myDynamicProxy.test; import java.util.Date; public interface IEcho { public void echo(); public int echo(int aa); public Boolean echo1(int aa,String user); public long getCurrentType(); public Date getDate(String aa); public ObjectModel echo(ObjectModel model); public char getChar(); }
业务接口实现类EchoEn
package qhy.demo.javassist.myDynamicProxy.test; import java.util.Date; public class EchoEn implements IEcho { @Override public void echo() { System.out.println("hello "+233434+"!"); } @Override public long getCurrentType() { System.out.println("getCurrentType"); return System.currentTimeMillis(); } @Override public Boolean echo1(int aa, String user) { System.out.println("getDate;param="+aa+","+user); // TODO Auto-generated method stub return true; } @Override public char getChar() { return 'A'; } @Override public Date getDate(String aa) { System.out.println("getDate;param="+aa); // TODO Auto-generated method stub return null; } @Override public ObjectModel echo(ObjectModel model) { System.out.println("echo(ObjectModel model)>>>>>>>param="+model.getName()); ObjectModel result = new ObjectModel("郑文玉", 33, 10023L); return result; } @Override public int echo(int aa) { System.out.println("我是AAA"+aa+"!"); return -98; } }
代理模式接口实现类:TestInvocationHandler
package qhy.demo.javassist.myDynamicProxy.test; import java.lang.reflect.Method; import qhy.demo.javassist.myDynamicProxy.MyInvocationHandler; public class TestInvocationHandler implements MyInvocationHandler { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("执行前:拦截111111111111111"); Object result = method.invoke(proxy, args); System.out.println("执行后:拦截22222222222222222"); return result; } }
测试代码
package qhy.demo.javassist.myDynamicProxy.test; import qhy.demo.javassist.myDynamicProxy.MyProxy; public class Test { /** * Description: . <br/> * * @param args * @throws Exception */ public static void main(String[] args) throws Exception { IEcho echo = MyProxy.newProxyInstance(IEcho.class, EchoEn.class, TestInvocationHandler.class); echo.echo(); int aa = echo.echo(888); System.err.println(">>>>>>>>>>>>>>"+aa); Boolean bool = echo.echo1(555, "qihyyy"); System.err.println(">>>>>>>>>>>>>>"+bool); ObjectModel result = new ObjectModel("qiqi玉", 31, 6013L); ObjectModel objModel = echo.echo(result); System.err.println(">>>>objModel>>>>>>>>>>"+objModel.getName()+"--"+objModel.getAge()+"--"+objModel.getCurrentTime()); char cha = echo.getChar(); System.err.println(">>>>getChar>>>>>>>>>>"+cha); } }
输出结果:
发表评论
-
Java实现SPI基础工具类
2016-09-09 17:16 1301概述: 前端时间看了一下dubbo源码被它使用的基于SPI(s ... -
JSP COOKIE使用
2015-12-05 16:08 508原来一直在想要实现可 ... -
Jedis事务用法
2015-11-25 20:06 1745今天同事问了一个redis的问题,主要就是出现错误之后就把所有 ... -
zookeeper笔记
2015-11-24 08:17 342这个笔记是2013年初写的,当时学习solr发现solr使用了 ... -
jdk1.7安装之后切换不回去
2015-11-02 20:03 635错误现象: 在win7上安装过jdk1.7之后,然后把环境变量 ... -
hadoopMapReduce小例子
2015-03-28 21:08 489今天做了一个简单的mapreduce小程序,目的是熟悉一下怎么 ... -
VMware虚拟机搭建Hadoop集群
2014-12-05 22:07 976最近搭建了hadoop2.5的集群,在这里分享一下希望能帮助到 ... -
Hibernate代码生成插件(eclipse)
2014-05-04 12:31 822阅读对象: 有一些hibernate使用经验的开发人员; 介绍 ... -
eclipse文件同步插件
2014-04-29 17:41 651clipse同步插件用于指定两个目录(源目录和目标目录)做文件 ... -
修改WAS(WebSpehre)默认编码和jvm内存申请
2014-04-28 17:09 1143登陆WAS管理控制台,打开:服务器->应用程序服务器-& ... -
Apache HttpClient 代理、登陆访问百度开放平台
2014-04-23 17:50 834最近做了下使用httpclient登陆百度开放平台获取G ... -
windows下编写mapreduce程序
2014-04-20 09:51 786配置linux的hadoop环境比较繁琐,为了方便的编写 ... -
RMI随机生成端口解决方法(结合spring)
2014-04-20 08:20 2993RMI有一个网络端口和一个数据端口,网络端口我们在程序里 ... -
WAS(WebSphere)修改端口
2014-04-20 07:58 41071、修改管理页面端口(默认:9060) a>进入控制台页 ...
相关推荐
"ibatis_struts2"表示iBatis和Struts2的集成使用,"java_ssi"可能是指在Java环境下实现的SSI功能,"myeclipse_ssi"则表明在MyEclipse中进行了SSI相关的开发工作。这些标签为理解项目的技术栈提供了指导。 压缩包内...
本主题聚焦于使用SSI框架实现的动态二叉树,这是一个将数据结构与服务器端编程技术相结合的应用实例。在数据库管理中,动态二叉树能够有效地组织和展示数据,特别是对于层次结构明显的数据库结构,如组织结构、文件...
在本教程中,我们将深入探讨如何实现SSI框架,并构建一个功能完善的动态网页系统。 1. **SSI基本语法** SSI的基本语法以`<!--#`开头,`-->`结尾,中间插入不同的指令。例如,`<!--#include virtual="header....
- **登录状态**:如果用户已登录,可以使用SSI动态插入用户的个人信息或注销链接。 - **错误显示**:在登录失败时,可以通过SSI插入错误信息,而不是每次失败都刷新整个页面。 5. **安全性强化**: - **XSS防护*...
Struts是Apache软件基金会的一个开源项目,它基于Model-View-Controller设计模式,帮助开发者构建动态网站。在登录功能中,Struts通常会创建一个Action类来处理用户的登录请求,接收表单参数,并通过业务逻辑判断...
SSI框架,即Struts2、Spring和iBatis的集成框架,是Java Web开发中常见的技术栈,用于构建高效、可维护的企业级应用程序。这个压缩包文件“ssi_curd”很可能包含了一个基本的CRUD(创建、读取、更新、删除)操作的...
在Java环境下,我们可以使用各种框架来实现SSI功能,以提高网站的开发效率和可维护性。下面我们将详细探讨Java中的SSI框架搭建及其应用。 首先,理解SSI的基本概念是必要的。SSI主要通过在HTML文件中使用特定的指令...
FPGA之SSI接口协议实现 FPGA之SSI接口协议实现是指在 Field-Programmable Gate Array(现场可编程门阵列)中实现 Synchronous Serial Interface(同步串行接口)协议。SSI 是一种全双工的串行接口,允许芯片与多种...
"SSI"是软件开发中的一个集成框架,代表Struts、Spring和iBatis三个组件的组合。这个框架常用于构建企业级的Java Web应用程序,提供强大的MVC(模型-视图-控制器)架构支持,以及数据库操作和依赖注入功能。 **...
在本项目实战中,我们将探讨如何使用SSI(Server-Side Includes)技术,结合流行的Java Web框架如iBatis、Spring和Struts2,以及前端库jQuery UI的autocomplete组件,来实现一个高效的产品自动补全功能。这个功能...
开发者可以在XML配置文件或者注解中定义SQL语句,通过Java接口或类调用这些SQL,从而实现数据的增删改查操作。iBatis与Spring结合使用时,可以无缝集成到Spring的IoC容器中,实现事务管理和数据访问对象(DAO)的...
【标题】"java-ssi医疗系统"是一个基于Java技术栈的医疗信息系统,它采用Maven作为构建工具,结合Spring框架的三个核心组件——Spring、SpringMVC和Oracle数据库,为医疗机构提供了一整套功能完善的解决方案。...
基于SSI框架的开发的用户信息管理项目源码,当做毕业论文设计也是可以的,其中的功能都是好用的,而且也通俗易懂,对于初学SSI框架也是一个很好的练习。 注:程序操作数据的表名为USER2,需要在数据库建一个这样的...
**SSI(Server Side Includes)框架**是一种在服务器端执行的小型脚本语言,常用于动态网页的构建。它允许Web开发者在HTML文档中嵌入动态内容,如时间、日期、服务器变量等,而无需使用更复杂的服务器端技术如PHP或...
SSI,全称Server-Side Includes,是一种简单的服务器端脚本语言,主要用于网页动态包含静态内容。这个"SSI框架项目案例"提供了一个实践性的学习资源,适合对SSI技术感兴趣或者正在学习的朋友。通过下载并查看该项目...
在IT行业中,SSI(Struts2、Spring、iBatis)是一种常见的企业级应用开发框架组合,它集成了MVC设计模式、依赖注入以及持久层操作,大大提高了开发效率和代码的可维护性。本项目以"ssi框架实现的留言板"为例,将深入...
在Spring和Struts的集成中,iBatis作为数据访问对象(DAO)层,负责与数据库的交互,通过XML配置文件或注解定义SQL映射,实现了动态SQL和数据访问的定制化。 **Junit测试框架**: Junit是Java开发中最常用的单元...
《LabVIEW FPGA入门:实现串行同步接口(SSI)》 LabVIEW FPGA是NI(National Instruments)提供的一个强大的工具,允许用户使用图形化编程环境来设计和实现FPGA(Field Programmable Gate Array)应用程序。本篇...
在硬件设计中,采用Verilog语言实现SSI通信协议,这是一种硬件描述语言,用于描述数字系统的结构和行为。通过Verilog编程,可以创建出能够处理SSI协议的逻辑电路,实现编码器与主控系统的高效通信。 绝对值编码器与...
在Java Web开发领域,SSI(Struts2、Spring、iBatis)框架组合被誉为经典的“铁三角”架构,以其强大的功能和灵活性深受开发者喜爱。本篇文章将深入探讨这三个开源框架的核心概念、功能以及它们如何协同工作,帮助你...