support custom classLoader

This commit is contained in:
wenshao
2013-12-30 21:08:05 +08:00
parent 0d796ea632
commit 626a67d8cf
4 changed files with 35 additions and 16 deletions
+2 -2
View File
@@ -11,7 +11,7 @@
-->
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.37</version>
<version>1.1.38-SNAPSHOT</version>
<packaging>jar</packaging>
<name>fastjson</name>
@@ -23,7 +23,7 @@
<properties>
<junit.version>4.11</junit.version>
<gpg.skip>false</gpg.skip>
<gpg.skip>true</gpg.skip>
<javadoc.skip>false</javadoc.skip>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jdk.version>1.5</jdk.version>
@@ -148,7 +148,17 @@ public class ParserConfig {
protected final SymbolTable symbolTable = new SymbolTable();
public ParserConfig(){
protected ASMDeserializerFactory asmFactory = ASMDeserializerFactory.getInstance();
public ParserConfig() {
this(ASMDeserializerFactory.getInstance());
}
public ParserConfig(ClassLoader parentClassLoader){
this(new ASMDeserializerFactory(parentClassLoader));
}
public ParserConfig(ASMDeserializerFactory asmFactory){
primitiveClasses.add(boolean.class);
primitiveClasses.add(Boolean.class);
@@ -399,7 +409,7 @@ public class ParserConfig {
asmEnable = false;
}
if (ASMDeserializerFactory.getInstance().isExternalClass(clazz)) {
if (asmFactory.isExternalClass(clazz)) {
asmEnable = false;
}
@@ -446,7 +456,7 @@ public class ParserConfig {
}
try {
return ASMDeserializerFactory.getInstance().createJavaBeanDeserializer(this, clazz, type);
return asmFactory.createJavaBeanDeserializer(this, clazz, type);
// } catch (VerifyError e) {
// e.printStackTrace();
// return new JavaBeanDeserializer(this, clazz, type);
@@ -482,7 +492,7 @@ public class ParserConfig {
asmEnable = false;
}
if (ASMDeserializerFactory.getInstance().isExternalClass(clazz)) {
if (asmFactory.isExternalClass(clazz)) {
asmEnable = false;
}
@@ -491,7 +501,7 @@ public class ParserConfig {
}
try {
return ASMDeserializerFactory.getInstance().createFieldDeserializer(mapping, clazz, fieldInfo);
return asmFactory.createFieldDeserializer(mapping, clazz, fieldInfo);
} catch (Throwable e) {
// skip
}
@@ -42,11 +42,11 @@ import com.alibaba.fastjson.util.FieldInfo;
public class ASMDeserializerFactory implements Opcodes {
private static final ASMDeserializerFactory instance = new ASMDeserializerFactory();
private static final ASMDeserializerFactory instance = new ASMDeserializerFactory();
private ASMClassLoader classLoader = new ASMClassLoader();
private final ASMClassLoader classLoader;
private final AtomicLong seed = new AtomicLong();
private final AtomicLong seed = new AtomicLong();
public String getGenClassName(Class<?> clazz) {
return "Fastjson_ASM_" + clazz.getSimpleName() + "_" + seed.incrementAndGet();
@@ -60,7 +60,11 @@ public class ASMDeserializerFactory implements Opcodes {
}
public ASMDeserializerFactory(){
classLoader = new ASMClassLoader();
}
public ASMDeserializerFactory(ClassLoader parentClassLoader){
classLoader = new ASMClassLoader(parentClassLoader);
}
public final static ASMDeserializerFactory getInstance() {
@@ -183,9 +187,8 @@ public class ASMDeserializerFactory implements Opcodes {
mw.visitMethodInsn(INVOKEVIRTUAL, getType(DefaultJSONParser.class), "getSymbolTable",
"()" + getDesc(SymbolTable.class));
mw.visitVarInsn(BIPUSH, seperator);
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONLexerBase.class), "scanEnum", "(Ljava/lang/Class;"
+ getDesc(SymbolTable.class)
+ "C)Ljava/lang/Enum;");
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONLexerBase.class), "scanEnum",
"(Ljava/lang/Class;" + getDesc(SymbolTable.class) + "C)Ljava/lang/Enum;");
mw.visitTypeInsn(CHECKCAST, getType(fieldClass)); // cast
mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm"));
} else if (Collection.class.isAssignableFrom(fieldClass)) {
@@ -485,7 +488,8 @@ public class ASMDeserializerFactory implements Opcodes {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitVarInsn(ALOAD, 0);
mw.visitFieldInsn(GETFIELD, context.getClassName(), fieldInfo.getName() + "_asm_prefix__", "[C");
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONLexerBase.class), "scanFieldString", "([C)Ljava/lang/String;");
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONLexerBase.class), "scanFieldString",
"([C)Ljava/lang/String;");
mw.visitVarInsn(ASTORE, context.var(fieldInfo.getName() + "_asm"));
} else if (fieldClass.isEnum()) {
@@ -656,7 +660,7 @@ public class ASMDeserializerFactory implements Opcodes {
mw.visitVarInsn(ALOAD, context.var("lexer"));
mw.visitFieldInsn(GETSTATIC, getType(Feature.class), feature.name(), "L" + getType(Feature.class) + ";");
mw.visitMethodInsn(INVOKEVIRTUAL, getType(JSONLexerBase.class), "isEnabled", "(" + "L" + getType(Feature.class)
+ ";" + ")Z");
+ ";" + ")Z");
}
private void defineVarLexer(Context context, MethodVisitor mw) {
@@ -724,7 +728,8 @@ public class ASMDeserializerFactory implements Opcodes {
mw.visitVarInsn(ALOAD, context.var("instance"));
mw.visitVarInsn(LLOAD, context.var(fieldInfo.getName() + "_asm", 2));
if (fieldInfo.getMethod() != null) {
mw.visitMethodInsn(INVOKEVIRTUAL, getType(context.getClazz()), fieldInfo.getMethod().getName(), getDesc(fieldInfo.getMethod()));
mw.visitMethodInsn(INVOKEVIRTUAL, getType(context.getClazz()), fieldInfo.getMethod().getName(),
getDesc(fieldInfo.getMethod()));
if (!fieldInfo.getMethod().getReturnType().equals(Void.TYPE)) {
mw.visitInsn(POP);
}
@@ -20,6 +20,10 @@ public class ASMClassLoader extends ClassLoader {
public ASMClassLoader(){
super(getParentClassLoader());
}
public ASMClassLoader(ClassLoader parent){
super (parent);
}
static ClassLoader getParentClassLoader() {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();