Hibernate底层技术简介 拦截方法
2007-01-21 10:41
435 查看
(1)利用反射机制
下面有类Monkey,接口Carrier,Monkey类没有实现Carrier接口,自然也就没有对应的transport()和getNum()方法。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.asm;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class Monkey ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.asm;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public interface Carrier ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public void transport();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public int getNum();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
下面的类MonkeyProxy通过反射技术的Proxy代码模式,完成了Mokey对Carrier接口的动态实现。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.cglib;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.lang.reflect.Method;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import net.sf.cglib.proxy.InvocationHandler;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import net.sf.cglib.proxy.Proxy;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class MonkeyProxy implements InvocationHandler ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private int proxyNum = 0;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public Object invoke(Object proxy, Method method, Object[] args)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
throws Exception ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
if (method.getName().equalsIgnoreCase("transport")) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
proxyNum++;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
if (method.getName().equalsIgnoreCase("getNum")) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return new Integer(proxyNum);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return null;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void test() ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
ReflectCarrier cr = (ReflectCarrier) Proxy.newProxyInstance(this
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
.getClass().getClassLoader(),
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
new Class[] ...{ ReflectCarrier.class }, this);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cr.transport();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cr.transport();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.out.println("由Monkey传送了" + cr.getNum() + "个货物");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public static void main(String[] args) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
MonkeyProxy mp = new MonkeyProxy();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
mp.test();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
程序运行结果如下:
由Monkey传送了2个货物
从上面的代码可以看出,方法invoke(Object proxy, Method method, Object[] args)拦截了Carrier接口方法的调用,修改或者插入了自己的代码。在这个过程中需要接口的帮助,使proxy代理有针对性的实现对象的转换,生成一个代理接口的Proxy对象。
(2)和ASM技术相比,反射技术的Proxy并没有改变类的字节码,而ASM可以直接操作字节码,使得ASM的代码可以直接修改Class类,通过字节码拦截Class的方法,现举例如下。
Work代表一个工人,不断的生产零件。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.asm;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class Worker ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//public int num;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void produce()...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.out.println("Worker生产了1个零件!");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//num++;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
方法produce()并没有记录生产的零件个数,下面使用字节码的方式来增强这一方法。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.asm;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.Attribute;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.ClassAdapter;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.ClassVisitor;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.CodeVisitor;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.Constants;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.Type;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class WorkerClassVisitor extends ClassAdapter implements Constants ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/** *//**
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
* @param ClassVisitor cv
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
*/
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public WorkerClassVisitor(ClassVisitor cv) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
super(cv);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private static final String WORKER = Type.getType(Worker.class)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
.getInternalName();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private String className;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* (non-Javadoc)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
* @see org.objectweb.asm.ClassVisitor#visitMethod(int, java.lang.String, java.lang.String, java.lang.String[], org.objectweb.asm.Attribute)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
*/
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public CodeVisitor visitMethod(int access, String name, String desc,
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
String[] exceptions, Attribute attrs) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
CodeVisitor cd = cv.visitMethod(access, name, desc, exceptions, attrs);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if ("produce".equals(name))
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return new WorkerCodeVisitor(cd, className);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return cd;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public void visit(int version, int access, String name, String superName,
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
String[] interfaces, String sourceFile) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.className = name;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitField(ACC_PUBLIC, "num", "I", null, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
super.visit(version, access, name, superName, interfaces, sourceFile);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
在visitMethod()中,将CodeVisitor指向了子类WorkerCodeVisitor。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.asm;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.CodeAdapter;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.CodeVisitor;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.Constants;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class WorkerCodeVisitor extends CodeAdapter implements Constants...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/** *//**
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
* @param CodeVisitor cv
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
*/
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public WorkerCodeVisitor(CodeVisitor cv) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
super(cv);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private String className;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/** *//**
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
* @param cd
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
* @param className
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
*/
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public WorkerCodeVisitor(CodeVisitor cv, String className) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
super(cv);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.className = className;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void visitInsn( int opcode) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
if( opcode==RETURN) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//ALOAD 0: this
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//DUP
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//GETFIELD Worker.num: int
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//ICONST_1
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//IADD
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//PUTFIELD Worker.num: int
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitVarInsn(ALOAD,0);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitInsn(DUP);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitFieldInsn(GETFIELD, className,
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
"num", "I");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitInsn(ICONST_1);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitInsn(IADD);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitFieldInsn(PUTFIELD, className,
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
"num", "I");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitInsn(opcode);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
visitInsn()方法拦截了方法字节码的最后一行,即Return指令。在return之前,添加了注释中的指令。注意插入的指令实际上是num++;的字节码,这一点可以把Worker类中的注释去掉,使用byteCode view在Eclipse中即可看到。下面是测试代码。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.asm;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.lang.reflect.Field;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.lang.reflect.Method;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class WorkerReflectTest ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public static String CLASSNAME = "com.weportal.asm.Worker";
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public static void main(String[] args) throws Exception ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
WorkerReflectTest wt = new WorkerReflectTest();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Class cc = wt.loadClass(CLASSNAME);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Object obj = cc.newInstance();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Method produce = obj.getClass().getMethod("produce", null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
produce.invoke(obj, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
produce.invoke(obj, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
produce.invoke(obj, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Field fd = obj.getClass().getField("num");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.out.println("Worker已经生产了" + fd.getInt(obj) + "个零件!");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
private Class loadClass(String className) throws ClassNotFoundException ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
ClassLoader cl = new VisitorClassLoader(getClass().getClassLoader(),
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
className);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return cl.loadClass(className);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
程序运行结果如下:
Worker生产了1个零件!
Worker生产了1个零件!
Worker生产了1个零件!
Worker已经生产了3个零件!
WorkerReflectTest中使用的VisitorClassLoader是针对这个demo设计的ClassLoader。
参考《精通Hibernate》刘洋 著
下面有类Monkey,接口Carrier,Monkey类没有实现Carrier接口,自然也就没有对应的transport()和getNum()方法。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.asm;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class Monkey ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.asm;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public interface Carrier ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public void transport();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public int getNum();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
下面的类MonkeyProxy通过反射技术的Proxy代码模式,完成了Mokey对Carrier接口的动态实现。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.cglib;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.lang.reflect.Method;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import net.sf.cglib.proxy.InvocationHandler;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import net.sf.cglib.proxy.Proxy;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class MonkeyProxy implements InvocationHandler ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private int proxyNum = 0;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public Object invoke(Object proxy, Method method, Object[] args)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
throws Exception ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
if (method.getName().equalsIgnoreCase("transport")) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
proxyNum++;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
if (method.getName().equalsIgnoreCase("getNum")) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return new Integer(proxyNum);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return null;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void test() ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
ReflectCarrier cr = (ReflectCarrier) Proxy.newProxyInstance(this
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
.getClass().getClassLoader(),
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
new Class[] ...{ ReflectCarrier.class }, this);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cr.transport();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cr.transport();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.out.println("由Monkey传送了" + cr.getNum() + "个货物");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public static void main(String[] args) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
MonkeyProxy mp = new MonkeyProxy();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
mp.test();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
程序运行结果如下:
由Monkey传送了2个货物
从上面的代码可以看出,方法invoke(Object proxy, Method method, Object[] args)拦截了Carrier接口方法的调用,修改或者插入了自己的代码。在这个过程中需要接口的帮助,使proxy代理有针对性的实现对象的转换,生成一个代理接口的Proxy对象。
(2)和ASM技术相比,反射技术的Proxy并没有改变类的字节码,而ASM可以直接操作字节码,使得ASM的代码可以直接修改Class类,通过字节码拦截Class的方法,现举例如下。
Work代表一个工人,不断的生产零件。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.asm;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class Worker ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//public int num;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void produce()...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.out.println("Worker生产了1个零件!");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//num++;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
方法produce()并没有记录生产的零件个数,下面使用字节码的方式来增强这一方法。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.asm;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.Attribute;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.ClassAdapter;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.ClassVisitor;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.CodeVisitor;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.Constants;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.Type;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class WorkerClassVisitor extends ClassAdapter implements Constants ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/** *//**
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
* @param ClassVisitor cv
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
*/
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public WorkerClassVisitor(ClassVisitor cv) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
super(cv);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private static final String WORKER = Type.getType(Worker.class)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
.getInternalName();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private String className;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/**//* (non-Javadoc)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
* @see org.objectweb.asm.ClassVisitor#visitMethod(int, java.lang.String, java.lang.String, java.lang.String[], org.objectweb.asm.Attribute)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
*/
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public CodeVisitor visitMethod(int access, String name, String desc,
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
String[] exceptions, Attribute attrs) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
CodeVisitor cd = cv.visitMethod(access, name, desc, exceptions, attrs);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
if ("produce".equals(name))
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return new WorkerCodeVisitor(cd, className);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return cd;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public void visit(int version, int access, String name, String superName,
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
String[] interfaces, String sourceFile) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.className = name;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitField(ACC_PUBLIC, "num", "I", null, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
super.visit(version, access, name, superName, interfaces, sourceFile);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
在visitMethod()中,将CodeVisitor指向了子类WorkerCodeVisitor。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.asm;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.CodeAdapter;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.CodeVisitor;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import org.objectweb.asm.Constants;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class WorkerCodeVisitor extends CodeAdapter implements Constants...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/** *//**
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
* @param CodeVisitor cv
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
*/
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public WorkerCodeVisitor(CodeVisitor cv) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
super(cv);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
private String className;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
/** *//**
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
* @param cd
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
* @param className
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
*/
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public WorkerCodeVisitor(CodeVisitor cv, String className) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
super(cv);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
this.className = className;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public void visitInsn( int opcode) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
if( opcode==RETURN) ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//ALOAD 0: this
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//DUP
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//GETFIELD Worker.num: int
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//ICONST_1
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//IADD
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
//PUTFIELD Worker.num: int
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitVarInsn(ALOAD,0);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitInsn(DUP);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitFieldInsn(GETFIELD, className,
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
"num", "I");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitInsn(ICONST_1);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitInsn(IADD);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitFieldInsn(PUTFIELD, className,
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
"num", "I");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
cv.visitInsn(opcode);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
visitInsn()方法拦截了方法字节码的最后一行,即Return指令。在return之前,添加了注释中的指令。注意插入的指令实际上是num++;的字节码,这一点可以把Worker类中的注释去掉,使用byteCode view在Eclipse中即可看到。下面是测试代码。
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
package com.weportal.asm;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.lang.reflect.Field;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
import java.lang.reflect.Method;
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedBlock.gif)
public class WorkerReflectTest ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
public static String CLASSNAME = "com.weportal.asm.Worker";
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
public static void main(String[] args) throws Exception ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
WorkerReflectTest wt = new WorkerReflectTest();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Class cc = wt.loadClass(CLASSNAME);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Object obj = cc.newInstance();
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Method produce = obj.getClass().getMethod("produce", null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
produce.invoke(obj, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
produce.invoke(obj, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
produce.invoke(obj, null);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
Field fd = obj.getClass().getField("num");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
System.out.println("Worker已经生产了" + fd.getInt(obj) + "个零件!");
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockStart.gif)
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ContractedSubBlock.gif)
private Class loadClass(String className) throws ClassNotFoundException ...{
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
ClassLoader cl = new VisitorClassLoader(getClass().getClassLoader(),
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
className);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/InBlock.gif)
return cl.loadClass(className);
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedSubBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/ExpandedBlockEnd.gif)
}
![](http://images.csdn.net/syntaxhighlighting/OutliningIndicators/None.gif)
程序运行结果如下:
Worker生产了1个零件!
Worker生产了1个零件!
Worker生产了1个零件!
Worker已经生产了3个零件!
WorkerReflectTest中使用的VisitorClassLoader是针对这个demo设计的ClassLoader。
参考《精通Hibernate》刘洋 著
相关文章推荐
- Hibernate底层技术简介 CGLIB
- Hibernate底层技术简介 ASM
- Hibernate底层技术简介 JDBC编程
- 开源技术:Hibernate 3注释简介
- Hibernate中Restrictions类的方法简介(转)
- 开源技术:Hibernate 3注释简介
- 最近项目中用hibernate分页查询的底层方法
- hibernate简介(Session,几种状态,方法······等)
- 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:5.技术简介之Hibernate
- java框架简介1----Hibernate架构使用方法简介
- 最近项目中用hibernate分页查询的底层方法
- DOM技术简介之二_事件+属性+方法
- 当Dao层继承了HibernateDaoSupport,使用底层SQL语句,session获取的方法,以及解决关联查询no session的问题
- 博为峰JavaEE技术文章 ——MyBatis Hibernate 简介
- 用hibernate分页查询的底层方法
- API拦截方法一:PE简介
- 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:3.技术简介之MinaFilter——LoggingFilter (转)
- DOM技术简介之二_事件+属性+方法
- 博为峰JavaEE技术文章 ——MyBatis Hibernate 简介
- hibernate的增加、修改方法不生效,查询正常【事务没有拦截到导致的】