电脑键盘不管用失灵

void changeClass() throws Exception {
ClassPool pool = ClassPool.getDefault();
//获取一个Student类的CtClass对象
CtClass ctClass = pool.get("com.javassist.domain.Student");
//为ctClass设置一个父类
ctClass.setSuperclass(pool.get("com.javassist.domain.Person"));
//为cTclass对象添加一个属性name
ctClass.addField(CtField.make("private S", ctClass));
ctClass.addMethod(CtMethod.make("public void setName(String name){this.name =}", ctClass));
ctClass.addMethod(CtMethod.make("public String getName(){return this.}", ctClass));
//获取ctClass对象对应的Class对象student
Class student = ctClass.toClass();
//对student类进行内省,得到对象BeanInfo
BeanInfo beanInfo = Introspector.getBeanInfo(student, Object.class);
//获取beanInfo的方法描述对象
MethodDescriptor[] descriptors = beanInfo.getMethodDescriptors();
for (int i = 0; i & descriptors. i++) {
System.out.println(descriptors[i].getName());
System.out.println(descriptors.length);
PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
for (int i = 0; i & propertyDescriptors. i++) {
System.out.println(propertyDescriptors[i].getDisplayName());
阅读(...) 评论()基于javassist实现对接口的动态代理引擎 - cuishen - ITeye技术网站
博客分类:
一提到jdk中的java.lang.reflect.Proxy,用过spring,hibernate等框架的人应该都有所了解,对!就是动态代理。AOP - 面向切面编程 - 就是基于动态代理实现的。
平日里项目中用spring aop框架进行日志拦截和声明式事务处理确实很方便好用,从另一种角度将代码解耦,极大的提高了代码的灵活性和可扩展性,在获益的同时我们不得不惊叹aop框架的神奇,但是静下心来想一想:它的核心 - 动态代理 - 其实是依靠运行时动态在内存中实现要代理的接口,并在所有接口的方法实现中反射java.lang.reflect.InvocationHandler的invoke方法;所以要用动态代理就必须先实现自己的InvocationHandler;返回给用户的是代理对象本身,而非接口的原有实现。
想明白了代理的本质,实现它就很容易了,我们可以借助开源的动态生成字节码/类的项目,如:
Byte Code Engineering Library (BCEL) - 在实际的JVM 指令层次上进行操作,提供在运行时在内存中动态生成类的支持
Javassist - 提供类似BCEL的功能,不过它更强调源代码级别的工作,对于程序员来说更加容易上手
好了,废话不多说了,现在看看我用Javassist实现的动态代理,提供接近java.lang.reflect.Proxy的功能
package com.cuishen.myA
import java.lang.reflect.M
import javassist.CannotCompileE
import javassist.ClassP
import javassist.CtC
import javassist.NotFoundE
import javassist.CtM
import javassist.CtNewM
* 基于javassist实现的动态代理类,即在运行时在内存中动态生成要代理的接口的实现,并在接口的方法实现中反射
* com.cuishen.myAop.InterceptorHandler(拦截器接口)的invoke方法,所以在使用本代理之前请先实现
* 拦截器接口。本代理提供接近java.lang.reflect.Proxy的功能
* @author cuishen
* @version 1.0
* @see com.cuishen.myAop.InterceptorHandler
* @see java.lang.reflect.Proxy
public class MyProxyImpl {
/** 动态代理类的类名后缀 */
private final static String PROXY_CLASS_NAME_SUFFIX = "$MyProxy_";
/** 拦截器接口 */
private final static String INTERCEPTOR_HANDLER_INTERFACE = "com.cuishen.myAop.InterceptorHandler";
/** 动态代理类的类名索引,防止类名重复 */
private static int proxyClassIndex = 1;
* 暴露给用户的动态代理接口,返回某个接口的动态代理对象,注意本代理实现需和com.cuishen.myAop.InterceptorHandler拦截器配合
* 使用,即用户要使用本动态代理,需先实现com.cuishen.myAop.InterceptorHandler拦截器接口
* 使用方法如下:
* StudentInfoService studentInfo = (StudentInfoService)MyProxyImpl.newProxyInstance(String, String, String);
* &br&studentInfo.方法调用;
* @param interfaceClassName String 要动态代理的接口类名, e.g test.StudentInfoService
* @param classToProxy String 要动态代理的接口的实现类的类名, e.g test.StudentInfoServiceImpl
* @param interceptorHandlerImplClassName String 用户提供的拦截器接口的实现类的类名
* @return Object 返回某个接口的动态代理对象
* @throws InstantiationException
* @throws IllegalAccessException
* @throws NotFoundException
* @throws CannotCompileException
* @throws ClassNotFoundException
* @see com.cuishen.myAop.InterceptorHandler
public static Object newProxyInstance(String interfaceClassName, String classToProxy, String interceptorHandlerImplClassName) throws InstantiationException, IllegalAccessException, NotFoundException, CannotCompileException, ClassNotFoundException {
Class interfaceClass = Class.forName(interfaceClassName);
Class interceptorHandlerImplClass = Class.forName(interceptorHandlerImplClassName);
return dynamicImplementsInterface(classToProxy, interfaceClass, interceptorHandlerImplClass);
* 动态实现要代理的接口
* @param classToProxy String 要动态代理的接口的实现类的类名, e.g test.StudentInfoServiceImpl
* @param interfaceClass Class 要动态代理的接口类, e.g test.StudentInfoService
* @param interceptorHandlerImplClass Class 用户提供的拦截器接口的实现类
* @return Object 返回某个接口的动态代理对象
* @throws NotFoundException
* @throws CannotCompileException
* @throws InstantiationException
* @throws IllegalAccessException
private static Object dynamicImplementsInterface(String classToProxy, Class interfaceClass, Class interceptorHandlerImplClass) throws NotFoundException, CannotCompileException, InstantiationException, IllegalAccessException {
ClassPool cp = ClassPool.getDefault();
String interfaceName = interfaceClass.getName();
//动态指定代理类的类名
String proxyClassName = interfaceName + PROXY_CLASS_NAME_SUFFIX + proxyClassIndex++;
//要实现的接口的包名+接口名
String interfaceNamePath = interfaceN
CtClass ctInterface = cp.getCtClass(interfaceNamePath);
CtClass cc = cp.makeClass(proxyClassName);
cc.addInterface(ctInterface);
Method [] methods = interfaceClass.getMethods();
for(int i = 0; i & methods. i++) {
Method method = methods[i];
dynamicImplementsMethodsFromInterface(classToProxy, cc, method, interceptorHandlerImplClass, i);
return (Object)cc.toClass().newInstance();
* 动态实现接口里的方法
* @param classToProxy String 要动态代理的接口的实现类的类名, e.g test.StudentInfoServiceImpl
* @param implementer CtClass 动态代理类的包装
* @param methodToImpl Method 动态代理类里面要实现的接口方法的包装
* @param interceptorClass Class 用户提供的拦截器实现类
* @param methodIndex int 要实现的方法的索引
* @throws CannotCompileException
private static void dynamicImplementsMethodsFromInterface(String classToProxy, CtClass implementer, Method methodToImpl, Class interceptorClass, int methodIndex) throws CannotCompileException {
String methodCode = generateMethodCode(classToProxy, methodToImpl, interceptorClass, methodIndex);
CtMethod cm = CtNewMethod.make(methodCode, implementer);
implementer.addMethod(cm);
* 动态组装方法体,当然代理里面的方法实现并不是简单的方法拷贝,而是反射调用了拦截器里的invoke方法,并将接收到的参数进行传递
* @param classToProxy String 要动态代理的接口的实现类的类名, e.g test.StudentInfoServiceImpl
* @param methodToImpl Method 动态代理类里面要实现的接口方法的包装
* @param interceptorClass Class 用户提供的拦截器实现类
* @param methodIndex int 要实现的方法的索引
* @return String 动态组装的方法的字符串
private static String generateMethodCode(String classToProxy, Method methodToImpl, Class interceptorClass, int methodIndex) {
String methodName = methodToImpl.getName();
String methodReturnType = methodToImpl.getReturnType().getName();
Class []parameters = methodToImpl.getParameterTypes();
Class []exceptionTypes = methodToImpl.getExceptionTypes();
StringBuffer exceptionBuffer = new StringBuffer();
//组装方法的Exception声明
if(exceptionTypes.length & 0) exceptionBuffer.append(" throws ");
for(int i = 0; i & exceptionTypes. i++) {
if(i != exceptionTypes.length - 1) exceptionBuffer.append(exceptionTypes[i].getName()).append(",");
else exceptionBuffer.append(exceptionTypes[i].getName());
StringBuffer parameterBuffer = new StringBuffer();
//组装方法的参数列表
for(int i = 0; i & parameters. i++) {
Class parameter = parameters[i];
String parameterType = parameter.getName();
//动态指定方法参数的变量名
String refName = "a" +
if(i != parameters.length - 1) parameterBuffer.append(parameterType).append(" " + refName).append(",");
else parameterBuffer.append(parameterType).append(" " + refName);
StringBuffer methodDeclare = new StringBuffer();
//方法声明,由于是实现接口的方法,所以是public
methodDeclare.append("public ").append(methodReturnType).append(" ").append(methodName).append("(").append(parameterBuffer).append(")").append(exceptionBuffer).append(" {\n");
String interceptorImplName = interceptorClass.getName();
methodDeclare.append(INTERCEPTOR_HANDLER_INTERFACE).append(" interceptor = new ").append(interceptorImplName).append("();\n");
//反射调用用户的拦截器接口
methodDeclare.append("Object returnObj = interceptor.invoke(Class.forName(\"" + classToProxy + "\").newInstance(), Class.forName(\"" + classToProxy + "\").getMethods()[" + methodIndex + "], ");
//传递方法里的参数
if(parameters.length & 0) methodDeclare.append("new Object[]{");
for(int i = 0; i & parameters. i++) {
//($w) converts from a primitive type to the corresponding wrapper type: e.g.
//Integer i = ($w)5;
if(i != parameters.length - 1) methodDeclare.append("($w)a" + i + ",");
else methodDeclare.append("($w)a" + i);
if(parameters.length & 0) methodDeclare.append("});\n");
else methodDeclare.append("null);\n");
//对调用拦截器的返回值进行包装
if(methodToImpl.getReturnType().isPrimitive()) {
if(methodToImpl.getReturnType().equals(Boolean.TYPE)) methodDeclare.append("return ((Boolean)returnObj).booleanValue();\n");
else if(methodToImpl.getReturnType().equals(Integer.TYPE)) methodDeclare.append("return ((Integer)returnObj).intValue();\n");
else if(methodToImpl.getReturnType().equals(Long.TYPE)) methodDeclare.append("return ((Long)returnObj).longValue();\n");
else if(methodToImpl.getReturnType().equals(Float.TYPE)) methodDeclare.append("return ((Float)returnObj).floatValue();\n");
else if(methodToImpl.getReturnType().equals(Double.TYPE)) methodDeclare.append("return ((Double)returnObj).doubleValue();\n");
else if(methodToImpl.getReturnType().equals(Character.TYPE)) methodDeclare.append("return ((Character)returnObj).charValue();\n");
else if(methodToImpl.getReturnType().equals(Byte.TYPE)) methodDeclare.append("return ((Byte)returnObj).byteValue();\n");
else if(methodToImpl.getReturnType().equals(Short.TYPE)) methodDeclare.append("return ((Short)returnObj).shortValue();\n");
methodDeclare.append("return (" + methodReturnType + ")returnO\n");
methodDeclare.append("}");
System.out.println(methodDeclare.toString());
return methodDeclare.toString();
我也提供了类似于java.lang.reflect.InvocationHandler的接口,我暂且称其为拦截器接口,要用我的代理,就得先实现它
package com.cuishen.myA
import java.lang.reflect.M
* 拦截器接口,用户使用com.cuishen.myAop.MyProxyImpl动态代理前,请先实现本接口,
* 在执行动态代理对象的方法时会自动反射到invoke方法,被代理的对象、方法和参数将做为
* 参数传递给invoke方法
* @author cuishen
* @version 1.0
* @see com.cuishen.myAop.MyProxyImpl
public interface InterceptorHandler {
* 调用动态代理对象的方法将反射本方法,可在本方法实现中添加类似AOP的事前事后操作,只有在本方法体中加入如下代码
* Object returnObj = method.invoke(obj, args);
* return returnO
* 被代理的方法才会被执行,返回值将返回给代理最后返回给程序
* @param obj Object 被代理的对象
* @param method Method 被代理对象的方法
* @param args Object[] 被代理对象的方法的参数
* @return Object 被代理对象的方法执行后的返回值
* @throws Throwable
public Object invoke(Object obj, Method method, Object[] args) throws T
(570.7 KB)
下载次数: 289
论坛回复 /
(0 / 2687)
浏览: 207352 次
来自: 上海
import com.sse.monitor.bean.Mes ...
楼主,求源码,万分感谢() ...
注意: 网上有人说IE8以下不支持Max-Age, 上面的代码 ...
刚接触socket,不是太明白,楼主的例子里面工具给的不是很全 ...ASM及字节码(1)
使用javassist动态注入代码
&&&&Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作为JBoss实现动态AOP框架。
& & &关于java字节码的处理,目前有很多工具,如bcel,asm。不过这些都需要直接跟虚拟机指令打交道。如果你不想了解虚拟机指令,可以采用javassist。javassist是jboss的一个子项目,其主要的优点,在于简单,而且快速。直接使用java编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构,或者动态生成类。
&&& 下面通过一个简单的例子,通过javassist来实现如何动态注入代码。
&&& 假设,存在类A,如下:
public class A {
public void method() {
for (int i = 0; i & 1000000; i++) {
System.out.println(&method1&);
测试类B1如下:
public class B1 {
public static void main(String[] args) {
A a = new A();
a.method();
现在想统计一下method的执行时间,为了减少工作量,通过动态注入代码的形式来实现,B2类。
import javassist.CannotCompileE
import javassist.ClassP
import javassist.CtC
import javassist.CtM
import javassist.CtNewM
import javassist.NotFoundE
public class B2 {
* @param args
public static void main(String[] args) {
CtClass ctC
// 用于取得字节码类,必须在当前的classpath中,使用全称
ctClass = ClassPool.getDefault().get(&com.A&);
// 需要修改的方法名称
String mname = &method&;
CtMethod mold = ctClass.getDeclaredMethod(mname);
// 修改原有的方法名称
String nname = mname + &$impl&;
mold.setName(nname);
// 创建新的方法,复制原来的方法
CtMethod mnew = CtNewMethod.copy(mold, mname, ctClass, null);
// 主要的注入代码
StringBuffer body = new StringBuffer();
body.append(&{\nlong start = System.currentTimeMillis();\n&);
// 调用原有代码,类似于method();($$)表示所有的参数
body.append(nname + &($$);\n&);
body.append(&System.out.println(\&Call to method & + mname
+ & took \& +\n (System.currentTimeMillis()-start) + &
+ &\& ms.\&);\n&);
body.append(&}&);
// 替换新方法
mnew.setBody(body.toString());
// 增加新方法
ctClass.addMethod(mnew);
// 类已经更改,注意不能使用A a=new A();,因为在同一个classloader中,不允许装载同一个类两次
A a = (A) ctClass.toClass().newInstance();
a.method();
} catch (NotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (CannotCompileException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
这只是简单的一个应用。javassist还提供了很多的功能,用于更改类结构。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:651983次
积分:7043
积分:7043
排名:第2750名
原创:96篇
转载:341篇
评论:54条
(3)(1)(3)(1)(4)(2)(24)(20)(22)(22)(14)(27)(38)(47)(4)(15)(7)(6)(5)(2)(3)(1)(1)(1)(1)(2)(18)(2)(7)(1)(1)(2)(1)(3)(3)(2)(2)(2)(2)(2)(3)(13)(2)(4)(6)(4)(22)(18)(12)(34)(1)不得不说的AOP——基于Javassist的动态代理实现。
- ITeye技术网站
博客分类:
关键词:AOP、SOC、代理模式、动态代理。
上一话,我提到了一个重要的概念就是SOC,即关注点分离。为什么要分离关注点,因为这样可以让我们更加简单而富有条理的去处理这个繁杂的世界。AOP就是SOC的一种体现。
什么是AOP?
AOP全程是Aspect Oriented Programming意即面向切面编程。他并不是什么OOP的替代技术,只是OOP的一种延续。使用SOC的思想,去解耦,去降低问题的复杂度。那么,为什么要叫做面向切面编程呢?想想一下,当你在软件开发设计类的时候,会不会发现,有些逻辑或者功能,是每个类或者说大多数类都需要完成的呢?比如异常/错误处理,比如系统日志记录,比如持久化中的事务处理。与其一个一个的实现,为什么不能把他们单独提取出来加以处理呢。如果说把这些类平行的放在一起。这些公共的部分刚好并排在一起,能够一刀切下。可能这就是切面概念的由来,呵呵。AOP就是为了解决上述问题而出现的。
为什么要提代理模式。因为AOP的广泛实现都是通过动态代理,而动态代理又不得不说代理模式。
代理模式,顾名思义,就是对一个类的访问,变为访问这个类的代理人。经由代理再访问这个类。(代理与被代理的类实现了相同的接口,因此客户感觉不到通过代理访问这个类和直接访问这个类的区别)
为什么需要代理呢,因为一个良好的设计不应该轻易的修改。这正是开闭原则的体现:一个良好的设计应该对修改关闭,对扩展开放。而代理正是为了扩展类而存在的。他可以控制对现有类(就是需要被代理的类)服务的访问,通俗的解释就是 可以拦截对于现有类方法的调用并做些处理。
而动态代理,是指在运行期动态的为指定的类生成其代理类。(需要相关的运行时编译技术,)
AOP如Spring的AOP实现就是以这种方式实现的。他使用动态生成的代理类拦截了现有类的“切点”。并进行控制,使得这些切面的逻辑完全与该类脱离,实现了关注点分离。
下面附上我用Javassist实现的简单动态代理。(Javassist是一个运行时编译库,他能动态的生成或修改类的字节码,类似的有ASM和CGLIB,大多数框架就是基于后者实现的)
package com.
import javassist.CtM
import javassist.ClassP
import javassist.CtC
import javassist.CtC
import javassist.CtF
import javassist.CannotCompileE
import javassist.NotFoundE
* 基于Javassist动态生成字节码实现简单的动态代理
* Dynamic Proxy based on Javassist
* @author:godsong
* @version:1.01
public class DProxy {
* 动态生成的代理类名前缀
* prefix name for Proxy
private static final String PROXY_CLASS_NAME=".Gproxy$";
* 代理类名索引 用于标示一个唯一的代理类(具体的代理类名为Gproxy$n)
* index for generate a unique proxy class
private static int proxyIndex=1;
* 代理拦截器(利用继承减少动态构造的字节码)
* Proxy interceptor(desingn for inherit)
protected Int
* Prohibit instantiation
* 利用私有构造函数阻止该类实例化
private DProxy(){}
protected DProxy(Interceptor interceptor){
this.interceptor=
* 创建动态代理的工厂方法
* static factory method for create proxy
* @param targetClass :被代理的类型
* @param interceptor 拦截器实例
* @return 返回动态代理实例
它实现了targerClass的所有接口。
因此可以向上转型为这些之中的任意接口
public static Object createProxy(Class&?& targetClass,Interceptor interceptor){
int index=0;
/*获得运行时类的上下文*/
ClassPool pool=ClassPool.getDefault();
/*动态创建代理类*/
CtClass proxy=pool.makeClass(targetClass.getPackage().getName()+PROXY_CLASS_NAME+proxyIndex++);
/*获得DProxy类作为代理类的父类*/
CtClass superclass=pool.get("com.lifewool.DProxy");
proxy.setSuperclass(superclass);
/*获得被代理类的所有接口*/
CtClass[] interfaces=pool.get(targetClass.getName()).getInterfaces();
for(CtClass i:interfaces){
/*动态代理实现这些接口*/
proxy.addInterface(i);
/*获得结构中的所有方法*/
CtMethod[] methods=i.getDeclaredMethods();
for(int n=0;n&methods.n++){
CtMethod m=methods[n];
/*构造这些Method参数 以便传递给拦截器的interceptor方法*/
StringBuilder fields=new StringBuilder();
fields.append("private static java.lang.reflect.Method method"+index);
fields.append("=Class.forName(\"");
fields.append(i.getName());
fields.append("\").getDeclaredMethods()[");
fields.append(n);
fields.append("];");
/*动态编译之*/
CtField cf=CtField.make(fields.toString(), proxy);
proxy.addField(cf);
GenerateMethods(pool,proxy,m,index);
/*创建构造方法以便注入拦截器*/
CtConstructor cc=new CtConstructor(new CtClass[]{pool.get("com.lifewool.Interceptor")}, proxy);
cc.setBody("{super($1);}");
proxy.addConstructor(cc);
//proxy.writeFile();
return proxy.toClass().getConstructor(Interceptor.class).newInstance(interceptor);
}catch(Exception e){
e.printStackTrace();
* 动态生成生成方法实现(内部调用)
private static void GenerateMethods(ClassPool pool,CtClass proxy,CtMethod method,int index){
CtMethod cm=new CtMethod(method.getReturnType(), method.getName(), method.getParameterTypes(), proxy);
/*构造方法体*/
StringBuilder mbody=new StringBuilder();
mbody.append("{super.interceptor.intercept(this,method");
mbody.append(index);
mbody.append(",$args);}");
cm.setBody(mbody.toString());
proxy.addMethod(cm);
} catch (CannotCompileException e) {
e.printStackTrace();
catch (NotFoundException e){
e.printStackTrace();
客户端代码
public interface Interface {
void Action(int a);
class clazz implements Interface{
public void Action(int a) {
System.out.println("do Action"+a);
class MyInterceptor implements Interceptor{
public MyInterceptor(Object i){
proxyed=i;
public int intercept(Object instance, Method method, Object[] Args) {
System.out.println("before action");
method.invoke(this.proxyed, Args);
System.out.println("after action");
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
public class test {
* @param args
public static void main(String[] args) {
clazz c=new clazz();
Interface i=(Interface)DProxy.createProxy(clazz.class, new MyInterceptor(c));
i.Action(123);
before action
do Action123
after action
浏览: 16790 次
一样的报错。跟这个没关系No result defined f ...

我要回帖

更多关于 触摸按键失灵 的文章

 

随机推荐