diff --git a/src/main/java/org/beetl/core/om/AsmAAFactory.java b/src/main/java/org/beetl/core/om/AsmAAFactory.java index bdcec882c8f1f89aac4b5f445661bfd7740f562a..0f7f02fd3932258def198dd86fca4ad21072ab0f 100644 --- a/src/main/java/org/beetl/core/om/AsmAAFactory.java +++ b/src/main/java/org/beetl/core/om/AsmAAFactory.java @@ -1,6 +1,6 @@ package org.beetl.core.om; -import org.beetl.core.om.asm.ASMBeanFactory; +import org.beetl.core.om.asm.AsmBeanFactory; import java.lang.reflect.Modifier; @@ -14,12 +14,12 @@ public class AsmAAFactory extends DefaultAAFactory { private static final boolean USE_PROPERTY_DESCRIPTOR = true; /** ASM JavaBean 工厂 */ - private final ASMBeanFactory asmBeanFactory; + private final AsmBeanFactory asmBeanFactory; public AsmAAFactory() { super(); - //beetl 里主要通过JavaBean规范获取取属性,asmBeanFactory也可以直接设置通过fields来获取 - asmBeanFactory = new ASMBeanFactory(USE_PROPERTY_DESCRIPTOR); + // beetl 里主要通过JavaBean规范获取取属性,asmBeanFactory也可以直接设置通过fields来获取 + asmBeanFactory = new AsmBeanFactory(USE_PROPERTY_DESCRIPTOR); } @Override @@ -29,7 +29,6 @@ public class AsmAAFactory extends DefaultAAFactory { classAttrs.put(c, aa); return aa; } else { - // classAttrs.put(c, this.reflectBeanAA); return this.reflectBeanAA; } diff --git a/src/main/java/org/beetl/core/om/asm/ASMBeanFactory.java b/src/main/java/org/beetl/core/om/asm/AsmBeanFactory.java similarity index 96% rename from src/main/java/org/beetl/core/om/asm/ASMBeanFactory.java rename to src/main/java/org/beetl/core/om/asm/AsmBeanFactory.java index 5f355a2fe7222d748fba7f0ca62a8d47e6d1c284..f0af7793d9afb638b8b9c48bb5802f4929d0fbb5 100644 --- a/src/main/java/org/beetl/core/om/asm/ASMBeanFactory.java +++ b/src/main/java/org/beetl/core/om/asm/AsmBeanFactory.java @@ -21,12 +21,12 @@ import org.beetl.core.om.ReflectBeanAA; * @author laozhaishaozuo@foxmail.com * */ -public class ASMBeanFactory { +public class AsmBeanFactory { /** DEBUG flag */ private static final boolean DEBUG = BeetlConfig.DEBUG; /** Log TAG */ - private static final String TAG = "ASMBeanFactory"; + private static final String TAG = "AsmBeanFactory"; private final Map, AttributeAccess> beanMap = new ConcurrentHashMap<>(); private final Map classLoaders = new ConcurrentHashMap<>(); @@ -39,11 +39,11 @@ public class ASMBeanFactory { boolean usePropertyDescriptor; - public ASMBeanFactory() { + public AsmBeanFactory() { usePropertyDescriptor = false; } - public ASMBeanFactory(boolean usePropertyDescriptor) { + public AsmBeanFactory(boolean usePropertyDescriptor) { this.usePropertyDescriptor = usePropertyDescriptor; } diff --git a/src/main/java/org/beetl/core/om/asm/BeanEnhanceConstants.java b/src/main/java/org/beetl/core/om/asm/BeanEnhanceConstants.java deleted file mode 100644 index d8d283a8c8ec8bf47aa53c4f04cb6bdaca584a00..0000000000000000000000000000000000000000 --- a/src/main/java/org/beetl/core/om/asm/BeanEnhanceConstants.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.beetl.core.om.asm; - -import org.beetl.core.om.AttributeAccess; - -/** - * @author laozhaishaozuo@foxmail.com - */ -final class BeanEnhanceConstants { - - private BeanEnhanceConstants() { - - } - - static final String METHOD_VALUE_OF = "valueOf"; - - static final String OBJECT_INTERNAL_NAME = "java/lang/Object"; - - static final String STRING_INTERNAL_NAME = "java/lang/String"; - - static final String BEETL_EXCEPTION_INTERNAL_NAME = "org/beetl/core/exception/BeetlException"; - - static final String STRING_BUILDER_INTERNAL_NAME = "java/lang/StringBuilder"; - - static final String TO_STRING_METHOD_NAME = "toString"; - - static final String TO_STRING_METHOD_DESCRIPTOR = "()Ljava/lang/String;"; - - static final String METHOD_TO_GENERATE = "value"; - - static final String METHOD_SIGNATURE = "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; - - static final String CLASS_NAME = AttributeAccess.class.getName(); - - static final String SUPER_CLASS_NAME = CLASS_NAME.replace('.', '/'); - - static final String GENETRATED_CLASS_SUFFIX = AttributeAccess.class.getSimpleName(); - - static final String GET_METHOD_NAME = "get"; - -} diff --git a/src/main/java/org/beetl/core/om/asm/BeanEnhanceUtils.java b/src/main/java/org/beetl/core/om/asm/BeanEnhanceUtils.java index b68b47fb9e9328e9d294e1b9c092a9fe611e0323..f7ccc02998e30b209606f224657a3b24b782d6ea 100644 --- a/src/main/java/org/beetl/core/om/asm/BeanEnhanceUtils.java +++ b/src/main/java/org/beetl/core/om/asm/BeanEnhanceUtils.java @@ -26,16 +26,17 @@ import org.beetl.ow2.asm.tree.FieldNode; * * @author laozhaishaozuo@foxmail.com */ -final class BeanEnhanceUtils { +final class BeanEnhanceUtils implements Constants { private BeanEnhanceUtils() { } - private static Set ignoreSet = new HashSet<>(); + /** 不获取的方法名,{@see #buildFieldDescMapByProperty} */ + private static final Set IGNORE_METHOD_NAME_SET = new HashSet<>(); static { - ignoreSet.add("getClass");// 避免获取到java.lang.Object.getClass()方法 + IGNORE_METHOD_NAME_SET.add("getClass");// 避免获取到java.lang.Object.getClass()方法 } /** @@ -89,18 +90,22 @@ final class BeanEnhanceUtils { for (PropertyDescriptor prop : propList) { curPropReadMethod = prop.getReadMethod(); - if ((curPropReadMethod != null) && !ignoreSet.contains(curPropReadMethod.getName())) { + if ((curPropReadMethod != null) && !IGNORE_METHOD_NAME_SET.contains(curPropReadMethod.getName())) { fieldDescs.add(new FieldDescription( - prop.getName(), Type.getType(curPropReadMethod.getReturnType()).toString(), - curPropReadMethod.getName(), getMethodDesc(curPropReadMethod) + prop.getName(), + Type.getType(curPropReadMethod.getReturnType()).toString(), + curPropReadMethod.getName(), + getMethodDesc(curPropReadMethod) )); // 2.x兼容,{@see ObjectUtil#getInvokder} if (prop.getPropertyType() == Boolean.class || prop.getPropertyType() == boolean.class) { fieldDescs.add(new FieldDescription( - curPropReadMethod.getName(), Type.getType(curPropReadMethod.getReturnType()).toString(), - curPropReadMethod.getName(), getMethodDesc(curPropReadMethod) + curPropReadMethod.getName(), + Type.getType(curPropReadMethod.getReturnType()).toString(), + curPropReadMethod.getName(), + getMethodDesc(curPropReadMethod) )); } @@ -131,7 +136,7 @@ final class BeanEnhanceUtils { private static String getMethodDesc(Method readMethod) { String descriptor = Type.getMethodDescriptor(readMethod); - return descriptor.substring(descriptor.indexOf(PunctuationConstants.LEFT_BRACKET)); + return descriptor.substring(descriptor.indexOf('(')); } private static void buildFieldDescMapByAsm(ClassDescription classDescription, ClassNode cn) { @@ -147,10 +152,14 @@ final class BeanEnhanceUtils { List fieldDescs = new ArrayList<>(fieldList.size() * 2); FieldDescription filedDesc = null; for (FieldNode fieldNode : fieldList) { - filedDesc = new FieldDescription(fieldNode.name, fieldNode.desc, - createGetterMethodName(classDescription, fieldNode.name), "()" + fieldNode.desc); + filedDesc = new FieldDescription( + fieldNode.name, + fieldNode.desc, + createGetterMethodName(classDescription, fieldNode.name), + "()" + fieldNode.desc + ); fieldDescs.add(filedDesc); - if (TypeDescriptorConstants.BOOLEAN_.equals(filedDesc.desc) && filedDesc.name.startsWith("is")) { + if (TypeDescriptor.BOOLEAN.equals(filedDesc.desc) && filedDesc.name.startsWith(MethodName.IS)) { fieldDescs.add(getBooleanFieldDescription(filedDesc)); } } @@ -158,51 +167,69 @@ final class BeanEnhanceUtils { } private static FieldDescription getBooleanFieldDescription(FieldDescription curFiledDesc) { - FieldDescription booleanDesc = new FieldDescription(); - String name = curFiledDesc.name.substring(2); - booleanDesc.name = name.substring(0, 1).toLowerCase() + name.substring(1); - booleanDesc.desc = curFiledDesc.desc; - booleanDesc.readMethodName = curFiledDesc.readMethodName; - booleanDesc.readMethodDesc = curFiledDesc.readMethodDesc; - return booleanDesc; + return new FieldDescription( + getFieldNameFromGetterMethod(curFiledDesc.name), + curFiledDesc.desc, + curFiledDesc.readMethodName, + curFiledDesc.readMethodDesc + ); } /** + * 将 getter 方法转换为字段名称 * + * @param getterMethodName getXXX 方法名称 + * @return {@param getterMethodName} 对应的字段名称 + */ + private static String getFieldNameFromGetterMethod(String getterMethodName) { + String name = getterMethodName.replaceFirst(MethodName.GET, ""); + return name.substring(0, 1).toLowerCase() + name.substring(1); + } + + /** + * 生成 getter 方法的方法描述符 */ private static MethodDescription getGeneralGetMethodDescription(Class target) { - MethodDescription md = new MethodDescription(); - md.name = BeanEnhanceConstants.GET_METHOD_NAME; + String getStr = MethodName.GET; try { - Method getMethod = target.getMethod(md.name, new Class[]{java.lang.Object.class}); - md.parameterInternalName = BeanEnhanceConstants.OBJECT_INTERNAL_NAME; - md.desc = getMethodDesc(getMethod); - md.returnTypeInternalName = getInternalName(getMethod.getReturnType().getName()); - return md; - } catch (Exception ex) { - // ingnore + Method getMethod = target.getMethod(getStr, Object.class); + return new MethodDescription( + getStr, + getMethodDesc(getMethod), + InternalName.OBJECT, + getInternalName(getMethod.getReturnType().getName()) + ); + } catch (Exception ignored) { } try { - Method getMethod = target.getMethod(md.name, new Class[]{java.lang.String.class}); - md.parameterInternalName = BeanEnhanceConstants.STRING_INTERNAL_NAME; - md.desc = getMethodDesc(getMethod); - md.returnTypeInternalName = getInternalName(getMethod.getReturnType().getName()); - return md; - } catch (Exception ex) { - // ingnore + Method getMethod = target.getMethod(getStr, String.class); + return new MethodDescription( + getStr, + getMethodDesc(getMethod), + InternalName.STRING, + getInternalName(getMethod.getReturnType().getName()) + ); + } catch (Exception ignored) { } return null; } + /** + * 创建 getter 方法的方法名称 + * + * @param classDescription 类描述符 + * @param propertyName 属性名 + * @return getter 方法的方法名称 + */ private static String createGetterMethodName(ClassDescription classDescription, String propertyName) { for (PropertyDescriptor ps : classDescription.propertyDescriptors) { if (ps.getName().equals(propertyName)) { return ps.getReadMethod().getName(); } - if (propertyName.startsWith("is") && ps.getReadMethod().getName().equals(propertyName)) { + if (propertyName.startsWith(MethodName.IS) && ps.getReadMethod().getName().equals(propertyName)) { return ps.getReadMethod().getName(); } } @@ -210,13 +237,19 @@ final class BeanEnhanceUtils { } static String getSimpleClassName(String className) { - return className.substring(className.lastIndexOf(PunctuationConstants.PERIOD) + 1); + return className.substring(className.lastIndexOf(".") + 1); } static String getInternalName(final String className) { - return className.replace(PunctuationConstants.PERIOD_CHAR, PunctuationConstants.SLASH_CHAR); + return className.replace('.', '/'); } + /** + * 将 Integer 数组转换为 int 数组 + * + * @param source Integer 数组 + * @return {@param source} 对应的 int 数组 + */ static int[] convertIntegerToPrimitiveType(Integer[] source) { int[] target = new int[source.length]; for (int i = 0; i < source.length; i++) { diff --git a/src/main/java/org/beetl/core/om/asm/Constants.java b/src/main/java/org/beetl/core/om/asm/Constants.java new file mode 100644 index 0000000000000000000000000000000000000000..c271f204e1b1480f33e76e5c134358ca521b747d --- /dev/null +++ b/src/main/java/org/beetl/core/om/asm/Constants.java @@ -0,0 +1,188 @@ +package org.beetl.core.om.asm; + +import org.intellij.lang.annotations.MagicConstant; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +public interface Constants { + + + /** + * 变量索引位置 + */ + @MagicConstant(intValues = { + VarIndex.THIS, + VarIndex.PARAM_BEAN, + VarIndex.PARAM_ATTR, + VarIndex.LOCAL_ATTR_STRING, + VarIndex.LOCAL_HASH_CODE, + VarIndex.LOCAL_INTERNAL_CLASS + }) + @Retention(RetentionPolicy.SOURCE) + @interface VarIndex { + /** 实例方法 this 变量位置 */ + int THIS = 0; + /** 方法中第一个参数的位置 */ + int PARAM_BEAN = 1; + /** 方法中第二个参数的位置 */ + int PARAM_ATTR = 2; + /** 本地变量对应attrName的toString变量 */ + int LOCAL_ATTR_STRING = 3; + /** 本地变量hashCode位置 */ + int LOCAL_HASH_CODE = 4; + /** 本地变量innerClass类型变量的位置 */ + int LOCAL_INTERNAL_CLASS = 5; + } + + /** + * 字节码类型描述符 + */ + @MagicConstant(stringValues = { + TypeDescriptor.BOOLEAN, + TypeDescriptor.BYTE, + TypeDescriptor.CHAR, + TypeDescriptor.DOUBLE, + TypeDescriptor.FLOAT, + TypeDescriptor.DOUBLE, + TypeDescriptor.INT, + TypeDescriptor.LONG, + TypeDescriptor.SHORT, + TypeDescriptor.VOID, + }) + @Retention(RetentionPolicy.SOURCE) + @interface TypeDescriptor { + /** 字节码中的类型描述符:boolean */ + String BOOLEAN = "Z"; + /** 字节码中的类型描述符:byte */ + String BYTE = "B"; + /** 字节码中的类型描述符:char */ + String CHAR = "C"; + /** 字节码中的类型描述符:double */ + String DOUBLE = "D"; + /** 字节码中的类型描述符:float */ + String FLOAT = "F"; + /** 字节码中的类型描述符:int */ + String INT = "I"; + /** 字节码中的类型描述符:long */ + String LONG = "J"; + /** 字节码中的类型描述符:short */ + String SHORT = "S"; + /** 字节码中的类型描述符:void */ + String VOID = "V"; + } + + /** + * 内部名 + */ + @MagicConstant(stringValues = { + InternalName.OBJECT, + InternalName.STRING, + InternalName.BEETL_EXCEPTION, + InternalName.STRING_BUILDER, + InternalName.ATTRIBUTE_ACCESS + }) + @Retention(RetentionPolicy.SOURCE) + @interface InternalName { + /** 内部名:{@link java.lang.Object} */ + String OBJECT = "java/lang/Object"; + /** 内部名:{@link java.lang.String} */ + String STRING = "java/lang/String"; + /** 内部名:{@link java.lang.Integer} */ + String INTEGER = "java/lang/Integer"; + /** 内部名:{@link java.lang.Byte} */ + String BYTE = "java/lang/Byte"; + /** 内部名:{@link java.lang.Boolean} */ + String BOOLEAN = "java/lang/Boolean"; + /** 内部名:{@link java.lang.Character} */ + String CHARACTER = "java.lang.Character"; + /** 内部名:{@link java.lang.Short} */ + String SHORT = "java/lang/Short"; + /** 内部名:{@link org.beetl.core.exception.BeetlException} */ + String BEETL_EXCEPTION = "org/beetl/core/exception/BeetlException"; + /** 内部名:{@link java.lang.StringBuilder} */ + String STRING_BUILDER = "java/lang/StringBuilder"; + /** 内部名:{@link org.beetl.core.om.AttributeAccess} */ + String ATTRIBUTE_ACCESS = "org/beetl/core/om/AttributeAccess"; + String DOUBLE = "java/lang/Double"; + String FLOAT = "java/lang/Float"; + String LONG = "java/lang/Long"; + } + + + /** + * 方法名 + */ + @MagicConstant(stringValues = { + MethodName.GET, + MethodName.IS, + MethodName.TO_STRING, + MethodName.VALUE, + MethodName.VALUE_OF + }) + @Retention(RetentionPolicy.SOURCE) + @interface MethodName { + /** 方法名:get */ + String GET = "get"; + /** 方法名:get */ + String IS = "is"; + /** 方法名:value */ + String VALUE = "value"; + /** 方法名:valueOf */ + String VALUE_OF = "valueOf"; + + /** 方法名:构造方法 */ + String CONSTRUCTOR = ""; + /** 方法名:{@link Object#equals(Object)} */ + String EQUALS = "equals"; + /** 方法名:{@link Object#hashCode()} */ + String HASH_CODE = "hashCode"; + /** 方法名:{@link Object#toString()} */ + String TO_STRING = "toString"; + /** 方法名:{@link StringBuilder#append(Object)} */ + String APPEND = "append"; + } + + /** + * 方法描述 + */ + @interface MethodDesc { + /** 方法描述:{@code Integer valueOf(int)} */ + String VALUE_OF_INTEGER = "(I)Ljava/lang/Integer;"; + /** 方法描述:{@code Boolean valueOf(boolean)} */ + String VALUE_OF_BOOLEAN = "(Z)Ljava/lang/Boolean;"; + /** 方法描述:{@code Byte valueOf(byte)} */ + String VALUE_OF_BYTE = "(B)Ljava/lang/Byte;"; + /** 方法描述:{@code Character valueOf(char)} */ + String VALUE_OF_CHARACTER = "(C)Ljava/lang/Character;"; + /** 方法描述:{@code Short valueOf(short)} */ + String VALUE_OF_SHORT = "(S)Ljava/lang/Short;"; + /** 方法描述:{@code Double valueOf(double)} */ + String VALUE_OF_DOUBLE = "(D)Ljava/lang/Double;"; + /** 方法描述:{@code Float valueOf(float)} */ + String VALUE_OF_FLOAT = "(F)Ljava/lang/Float;"; + /** 方法描述:{@code Long valueOf(long)} */ + String VALUE_OF_LONG = "(J)Ljava/lang/Long;"; + /** 方法描述:{@code toString()} */ + String TO_STRING = "()Ljava/lang/String;"; + /** 方法描述:{@code StringBuilder append(String)} */ + String APPEND_STRING_BUILDER = "(Ljava/lang/String;)Ljava/lang/StringBuilder;"; + /** 方法描述:{@code StringBuilder(String)} */ + String CONSTRUCTOR_STRING_BUILDER = "(Ljava/lang/String;)V"; + /** 方法描述:{@code BeetlException(String, String)} */ + String CONSTRUCTOR_BEETL_EXCEPTION = "(Ljava/lang/String;Ljava/lang/String;)V"; + /** 方法描述:{@code void m()} */ + String EMPTY_VOID = "()V"; + /** 方法描述:{@code int m()} */ + String EMPTY_INT = "()I"; + /** 方法描述:{@link org.beetl.core.om.AttributeAccess#value(java.lang.Object, java.lang.Object)} */ + String VALUE = "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"; + /** 方法描述:{@code boolean equals(Object)} */ + String EQUALS = "(Ljava/lang/Object;)Z"; + } + + /** 避免使用反射增加耗时 */ + String GEN_CLASS_SUFFIX = "AttributeAccess"; + /** 生成类的类名中的分隔符 */ + String GEN_SEP = "$"; +} diff --git a/src/main/java/org/beetl/core/om/asm/EnhanceClassGenerator.java b/src/main/java/org/beetl/core/om/asm/EnhanceClassGenerator.java index 308745b5ed090842caf8432ea3f8ed3fc78b841f..830c15dea6b438b2b7819f4d9748c08a59f7babd 100644 --- a/src/main/java/org/beetl/core/om/asm/EnhanceClassGenerator.java +++ b/src/main/java/org/beetl/core/om/asm/EnhanceClassGenerator.java @@ -82,35 +82,11 @@ import org.beetl.ow2.asm.Opcodes; * * @author laozhaishaozuo@foxmail.com */ -class EnhanceClassGenerator implements Opcodes { +class EnhanceClassGenerator implements Opcodes, Constants { /** - * 实例方法this变量位置 + * 私有构造方法 */ - private static final int VAR_THIS_INDEX = 0; - /** - * 方法中第一个参数的位置 - */ - private static final int VAR_BEAN_INDEX = 1; - /** - * 方法中第二个参数的位置 - */ - private static final int VAR_ATTR_INDEX = 2; - - /** - * 本地变量对应attrName的toString变量 - */ - private static final int LOCAL_VAR_ATTR_STRING_INDEX = 3; - - /** - * 本地变量hashCode位置 - */ - private static final int LOCAL_VAR_HASH_CODE_INDEX = 4; - /** - * 本地变量innerClass类型变量的位置 - */ - private static final int LOCAL_VAR_INTERNAL_CLASS_INDEX = 5; - private EnhanceClassGenerator() { } @@ -128,7 +104,7 @@ class EnhanceClassGenerator implements Opcodes { * @param usePropertyDescriptor 是否使{@link java.beans.PropertyDescriptor}来生成属性描述 */ static byte[] generate(Class beanClass, boolean usePropertyDescriptor) throws Exception { - return generate(beanClass, BeanEnhanceConstants.SUPER_CLASS_NAME, null, usePropertyDescriptor); + return generate(beanClass, InternalName.ATTRIBUTE_ACCESS, null, usePropertyDescriptor); } /** @@ -158,10 +134,10 @@ class EnhanceClassGenerator implements Opcodes { * @param superName 父类名称 */ static void generateDefaultConstruct(ClassWriter cw, String superName) { - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, MethodName.CONSTRUCTOR, MethodDesc.EMPTY_VOID, null, null); // 生成构造方法的字节码指令 mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, superName, "", "()V", false); + mv.visitMethodInsn(INVOKESPECIAL, superName, MethodName.CONSTRUCTOR, MethodDesc.EMPTY_VOID, false); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); @@ -169,7 +145,7 @@ class EnhanceClassGenerator implements Opcodes { } static String createGeneratedClassName(String className) { - return className + "$" + BeanEnhanceConstants.GENETRATED_CLASS_SUFFIX; + return className + Constants.GEN_SEP + GEN_CLASS_SUFFIX; } static String createGeneratedClassName(Class beanClass) { @@ -182,48 +158,53 @@ class EnhanceClassGenerator implements Opcodes { private static void generateMethod(ClassWriter cw, Class beanClass, boolean usePropertyDescriptor) { String internalClassName = BeanEnhanceUtils.getInternalName(beanClass.getName()); ClassDescription classDescription = BeanEnhanceUtils.getClassDescription(beanClass, usePropertyDescriptor); - MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, BeanEnhanceConstants.METHOD_TO_GENERATE, - BeanEnhanceConstants.METHOD_SIGNATURE, null, null); - + MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, MethodName.VALUE, MethodDesc.VALUE, null, null); mv.visitCode(); - // 有属性,需要调用getter方法 + // 有属性,需要调用 getter 方法 if (classDescription.hasField) { - generateMethodWithFileds(internalClassName, classDescription, mv); + generateMethodWithFields(internalClassName, classDescription, mv); } else { - generateMethodWithNoFiled(mv, classDescription, internalClassName); + generateMethodWithNoField(mv, classDescription, internalClassName); } mv.visitEnd(); } - private static void generateMethodWithFileds(String internalClassName, ClassDescription classDescription, + /** + * 为字段生成相应的方法 + * + * @param internalClassName 内部名 + * @param classDescription 类描述 + * @param mv asm 方法访问者 + */ + private static void generateMethodWithFields(String internalClassName, ClassDescription classDescription, MethodVisitor mv) { Label toStringLabel = new Label(); mv.visitLabel(toStringLabel); - mv.visitVarInsn(ALOAD, VAR_ATTR_INDEX); - mv.visitMethodInsn(INVOKEVIRTUAL, BeanEnhanceConstants.OBJECT_INTERNAL_NAME, - BeanEnhanceConstants.TO_STRING_METHOD_NAME, BeanEnhanceConstants.TO_STRING_METHOD_DESCRIPTOR, false); - mv.visitVarInsn(ASTORE, LOCAL_VAR_ATTR_STRING_INDEX);// 对应attrName的toString变量 + mv.visitVarInsn(ALOAD, VarIndex.PARAM_ATTR); + mv.visitMethodInsn(INVOKEVIRTUAL, InternalName.OBJECT, + MethodName.TO_STRING, MethodDesc.TO_STRING, false); + mv.visitVarInsn(ASTORE, VarIndex.LOCAL_ATTR_STRING);// 对应attrName的toString变量 Label hashCodeLabel = new Label(); mv.visitLabel(hashCodeLabel); - mv.visitVarInsn(ALOAD, LOCAL_VAR_ATTR_STRING_INDEX);// toString变量 - mv.visitMethodInsn(INVOKEVIRTUAL, BeanEnhanceConstants.OBJECT_INTERNAL_NAME, "hashCode", "()I", false); - mv.visitVarInsn(ISTORE, LOCAL_VAR_HASH_CODE_INDEX);// hashCode + mv.visitVarInsn(ALOAD, VarIndex.LOCAL_ATTR_STRING);// toString变量 + mv.visitMethodInsn(INVOKEVIRTUAL, InternalName.OBJECT, MethodName.HASH_CODE, MethodDesc.EMPTY_INT, false); + mv.visitVarInsn(ISTORE, VarIndex.LOCAL_HASH_CODE);// hashCode Label castLabel = new Label(); mv.visitLabel(castLabel); - mv.visitVarInsn(ALOAD, VAR_BEAN_INDEX);// 参数 bean + mv.visitVarInsn(ALOAD, VarIndex.PARAM_BEAN);// 参数 bean mv.visitTypeInsn(CHECKCAST, internalClassName); - mv.visitVarInsn(ASTORE, LOCAL_VAR_INTERNAL_CLASS_INDEX);// 对应internalClassName类型的变量 + mv.visitVarInsn(ASTORE, VarIndex.LOCAL_INTERNAL_CLASS);// 对应internalClassName类型的变量 Label l2 = new Label(); mv.visitLabel(l2); - mv.visitVarInsn(ILOAD, LOCAL_VAR_HASH_CODE_INDEX); + mv.visitVarInsn(ILOAD, VarIndex.LOCAL_HASH_CODE); Label[] lookupSwitchLabels = new Label[classDescription.fieldDescMap.size()]; int[] hashCodes = BeanEnhanceUtils - .convertIntegerToPrimitiveType(classDescription.fieldDescMap.keySet().toArray(new Integer[1])); + .convertIntegerToPrimitiveType(classDescription.fieldDescMap.keySet().toArray(new Integer[0])); for (int i = 0; i < lookupSwitchLabels.length; i++) { lookupSwitchLabels[i] = new Label(); } @@ -235,15 +216,14 @@ class EnhanceClassGenerator implements Opcodes { fieldDescs = classDescription.fieldDescMap.get(hashCodes[i]); mv.visitLabel(lookupSwitchLabels[i]); if (i == 0) { - mv.visitFrame(Opcodes.F_APPEND, 3, - new Object[]{BeanEnhanceConstants.STRING_INTERNAL_NAME, Opcodes.INTEGER, internalClassName}, 0, - null); + Object[] locals = new Object[]{InternalName.STRING, Opcodes.INTEGER, internalClassName}; + mv.visitFrame(Opcodes.F_APPEND, locals.length, locals, 0, null); } else { mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); } if (fieldDescs.size() == 1) { curFieldDesc = fieldDescs.get(0); - mv.visitVarInsn(ALOAD, LOCAL_VAR_INTERNAL_CLASS_INDEX);// 对应internalClassName类型的变量 + mv.visitVarInsn(ALOAD, VarIndex.LOCAL_INTERNAL_CLASS);// 对应internalClassName类型的变量 mv.visitMethodInsn(INVOKEVIRTUAL, internalClassName, curFieldDesc.readMethodName, curFieldDesc.readMethodDesc, false); addInvokeValueOfToPrimitive(mv, curFieldDesc.desc); @@ -253,111 +233,112 @@ class EnhanceClassGenerator implements Opcodes { } } - if (classDescription.generalGetMethodDesc != null && BeanEnhanceConstants.OBJECT_INTERNAL_NAME + if (classDescription.generalGetMethodDesc != null && InternalName.OBJECT .equals(classDescription.generalGetMethodDesc.parameterInternalName)) { // 是否有get(Object)方法 mv.visitLabel(df); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - mv.visitVarInsn(ALOAD, LOCAL_VAR_INTERNAL_CLASS_INDEX); - mv.visitVarInsn(ALOAD, VAR_ATTR_INDEX); - mv.visitMethodInsn(INVOKEVIRTUAL, internalClassName, BeanEnhanceConstants.GET_METHOD_NAME, + mv.visitVarInsn(ALOAD, VarIndex.LOCAL_INTERNAL_CLASS); + mv.visitVarInsn(ALOAD, VarIndex.PARAM_ATTR); + mv.visitMethodInsn(INVOKEVIRTUAL, internalClassName, MethodName.GET, classDescription.generalGetMethodDesc.desc, false); mv.visitInsn(ARETURN); - } else if (classDescription.generalGetMethodDesc != null && BeanEnhanceConstants.STRING_INTERNAL_NAME + } else if (classDescription.generalGetMethodDesc != null && InternalName.STRING .equals(classDescription.generalGetMethodDesc.parameterInternalName)) { // 是否有get(String)方法 mv.visitLabel(df); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - mv.visitVarInsn(ALOAD, LOCAL_VAR_INTERNAL_CLASS_INDEX); - mv.visitVarInsn(ALOAD, LOCAL_VAR_ATTR_STRING_INDEX); - mv.visitMethodInsn(INVOKEVIRTUAL, internalClassName, BeanEnhanceConstants.GET_METHOD_NAME, + mv.visitVarInsn(ALOAD, VarIndex.LOCAL_INTERNAL_CLASS); + mv.visitVarInsn(ALOAD, VarIndex.LOCAL_ATTR_STRING); + mv.visitMethodInsn(INVOKEVIRTUAL, internalClassName, MethodName.GET, classDescription.generalGetMethodDesc.desc, false); mv.visitInsn(ARETURN); } else { mv.visitLabel(df); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); - mv.visitTypeInsn(NEW, BeanEnhanceConstants.BEETL_EXCEPTION_INTERNAL_NAME); + mv.visitTypeInsn(NEW, InternalName.BEETL_EXCEPTION); mv.visitInsn(DUP); mv.visitLdcInsn("ATTRIBUTE_NOT_FOUND"); - mv.visitTypeInsn(NEW, BeanEnhanceConstants.STRING_BUILDER_INTERNAL_NAME); + mv.visitTypeInsn(NEW, InternalName.STRING_BUILDER); mv.visitInsn(DUP); mv.visitLdcInsn("属性未找到(" + classDescription.target.getName() + ") : "); - mv.visitMethodInsn(INVOKESPECIAL, BeanEnhanceConstants.STRING_BUILDER_INTERNAL_NAME, "", - "(Ljava/lang/String;)V", false); - mv.visitVarInsn(ALOAD, LOCAL_VAR_ATTR_STRING_INDEX); - mv.visitMethodInsn(INVOKEVIRTUAL, BeanEnhanceConstants.STRING_BUILDER_INTERNAL_NAME, "append", - "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); - mv.visitMethodInsn(INVOKEVIRTUAL, BeanEnhanceConstants.STRING_BUILDER_INTERNAL_NAME, - BeanEnhanceConstants.TO_STRING_METHOD_NAME, BeanEnhanceConstants.TO_STRING_METHOD_DESCRIPTOR, + mv.visitMethodInsn(INVOKESPECIAL, InternalName.STRING_BUILDER, MethodName.CONSTRUCTOR, + MethodDesc.CONSTRUCTOR_STRING_BUILDER, false); + mv.visitVarInsn(ALOAD, VarIndex.LOCAL_ATTR_STRING); + mv.visitMethodInsn(INVOKEVIRTUAL, InternalName.STRING_BUILDER, MethodName.APPEND, + MethodDesc.APPEND_STRING_BUILDER, false); + mv.visitMethodInsn(INVOKEVIRTUAL, InternalName.STRING_BUILDER, + MethodName.TO_STRING, MethodDesc.TO_STRING, false); - mv.visitMethodInsn(INVOKESPECIAL, BeanEnhanceConstants.BEETL_EXCEPTION_INTERNAL_NAME, "", - "(Ljava/lang/String;Ljava/lang/String;)V", false); + mv.visitMethodInsn(INVOKESPECIAL, InternalName.BEETL_EXCEPTION, MethodName.CONSTRUCTOR, + MethodDesc.CONSTRUCTOR_BEETL_EXCEPTION, false); mv.visitInsn(ATHROW); } mv.visitMaxs(1, 6); } - private static void generateMethodWithNoFiled(MethodVisitor mv, ClassDescription classDescription, + private static void generateMethodWithNoField(MethodVisitor mv, ClassDescription classDescription, String internalClassName) { Label castLabel = new Label(); mv.visitLabel(castLabel); - mv.visitVarInsn(ALOAD, VAR_BEAN_INDEX);// 参数 bean + mv.visitVarInsn(ALOAD, VarIndex.PARAM_BEAN);// 参数 bean mv.visitTypeInsn(CHECKCAST, internalClassName); mv.visitVarInsn(ASTORE, 3);// 此时不需要转换String与计算hashCode,所以是第三个变量 Label df = new Label(); - if (classDescription.generalGetMethodDesc != null && BeanEnhanceConstants.OBJECT_INTERNAL_NAME + if (classDescription.generalGetMethodDesc != null && InternalName.OBJECT .equals(classDescription.generalGetMethodDesc.parameterInternalName)) { mv.visitLabel(df); mv.visitFrame(Opcodes.F_APPEND, 1, new Object[]{internalClassName}, 0, null); mv.visitVarInsn(ALOAD, 3); - mv.visitVarInsn(ALOAD, VAR_ATTR_INDEX); - mv.visitMethodInsn(INVOKEVIRTUAL, internalClassName, BeanEnhanceConstants.GET_METHOD_NAME, + mv.visitVarInsn(ALOAD, VarIndex.PARAM_ATTR); + mv.visitMethodInsn(INVOKEVIRTUAL, internalClassName, MethodName.GET, classDescription.generalGetMethodDesc.desc, false); mv.visitInsn(ARETURN); - } else if (classDescription.generalGetMethodDesc != null && BeanEnhanceConstants.STRING_INTERNAL_NAME + } else if (classDescription.generalGetMethodDesc != null && InternalName.STRING .equals(classDescription.generalGetMethodDesc.parameterInternalName)) { Label toStringLabel = new Label(); mv.visitLabel(toStringLabel); - mv.visitVarInsn(ALOAD, VAR_ATTR_INDEX); - mv.visitMethodInsn(INVOKEVIRTUAL, BeanEnhanceConstants.OBJECT_INTERNAL_NAME, - BeanEnhanceConstants.TO_STRING_METHOD_NAME, BeanEnhanceConstants.TO_STRING_METHOD_DESCRIPTOR, + mv.visitVarInsn(ALOAD, VarIndex.PARAM_ATTR); + mv.visitMethodInsn(INVOKEVIRTUAL, InternalName.OBJECT, + MethodName.TO_STRING, MethodDesc.TO_STRING, false); mv.visitVarInsn(ASTORE, 4);// 对应attrName的toString变量 mv.visitLabel(df); mv.visitFrame(Opcodes.F_APPEND, 2, - new Object[]{internalClassName, BeanEnhanceConstants.STRING_INTERNAL_NAME}, 0, null); + new Object[]{internalClassName, InternalName.STRING}, 0, null); mv.visitVarInsn(ALOAD, 3);// internalClassName mv.visitVarInsn(ALOAD, 4);// attrName.toString() - mv.visitMethodInsn(INVOKEVIRTUAL, internalClassName, BeanEnhanceConstants.GET_METHOD_NAME, + mv.visitMethodInsn(INVOKEVIRTUAL, internalClassName, MethodName.GET, classDescription.generalGetMethodDesc.desc, false); mv.visitInsn(ARETURN); } else { Label toStringLabel = new Label(); mv.visitLabel(toStringLabel); - mv.visitVarInsn(ALOAD, VAR_ATTR_INDEX); - mv.visitMethodInsn(INVOKEVIRTUAL, BeanEnhanceConstants.OBJECT_INTERNAL_NAME, - BeanEnhanceConstants.TO_STRING_METHOD_NAME, BeanEnhanceConstants.TO_STRING_METHOD_DESCRIPTOR, + mv.visitVarInsn(ALOAD, VarIndex.PARAM_ATTR); + mv.visitMethodInsn(INVOKEVIRTUAL, InternalName.OBJECT, + MethodName.TO_STRING, MethodDesc.TO_STRING, false); mv.visitVarInsn(ASTORE, 4);// 对应attrName的toString变量 mv.visitLabel(df); - mv.visitFrame(Opcodes.F_APPEND, 2, - new Object[]{internalClassName, BeanEnhanceConstants.STRING_INTERNAL_NAME}, 0, null); - mv.visitTypeInsn(NEW, BeanEnhanceConstants.BEETL_EXCEPTION_INTERNAL_NAME); + + Object[] locals = new Object[]{internalClassName, InternalName.STRING}; + mv.visitFrame(Opcodes.F_APPEND, locals.length, locals, 0, null); + mv.visitTypeInsn(NEW, InternalName.BEETL_EXCEPTION); mv.visitInsn(DUP); mv.visitLdcInsn("ATTRIBUTE_NOT_FOUND"); - mv.visitTypeInsn(NEW, BeanEnhanceConstants.STRING_BUILDER_INTERNAL_NAME); + mv.visitTypeInsn(NEW, InternalName.STRING_BUILDER); mv.visitInsn(DUP); mv.visitLdcInsn("attribute : "); - mv.visitMethodInsn(INVOKESPECIAL, BeanEnhanceConstants.STRING_BUILDER_INTERNAL_NAME, "", - "(Ljava/lang/String;)V", false); + mv.visitMethodInsn(INVOKESPECIAL, InternalName.STRING_BUILDER, MethodName.CONSTRUCTOR, + MethodDesc.CONSTRUCTOR_STRING_BUILDER, false); mv.visitVarInsn(ALOAD, 4); - mv.visitMethodInsn(INVOKEVIRTUAL, BeanEnhanceConstants.STRING_BUILDER_INTERNAL_NAME, "append", - "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); - mv.visitMethodInsn(INVOKEVIRTUAL, BeanEnhanceConstants.STRING_BUILDER_INTERNAL_NAME, - BeanEnhanceConstants.TO_STRING_METHOD_NAME, BeanEnhanceConstants.TO_STRING_METHOD_DESCRIPTOR, + mv.visitMethodInsn(INVOKEVIRTUAL, InternalName.STRING_BUILDER, MethodName.APPEND, + MethodDesc.APPEND_STRING_BUILDER, false); + mv.visitMethodInsn(INVOKEVIRTUAL, InternalName.STRING_BUILDER, + MethodName.TO_STRING, MethodDesc.TO_STRING, false); - mv.visitMethodInsn(INVOKESPECIAL, BeanEnhanceConstants.BEETL_EXCEPTION_INTERNAL_NAME, "", - "(Ljava/lang/String;Ljava/lang/String;)V", false); + mv.visitMethodInsn(INVOKESPECIAL, InternalName.BEETL_EXCEPTION, MethodName.CONSTRUCTOR, + MethodDesc.CONSTRUCTOR_BEETL_EXCEPTION, false); mv.visitInsn(ATHROW); } mv.visitMaxs(1, 4); @@ -383,13 +364,13 @@ class EnhanceClassGenerator implements Opcodes { curFieldDesc = fieldDescs.get(i); mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null); mv.visitLdcInsn(curFieldDesc.name); - mv.visitVarInsn(ALOAD, LOCAL_VAR_ATTR_STRING_INDEX); - mv.visitMethodInsn(INVOKEVIRTUAL, BeanEnhanceConstants.OBJECT_INTERNAL_NAME, "equals", - "(Ljava/lang/Object;)Z", false); + mv.visitVarInsn(ALOAD, VarIndex.LOCAL_ATTR_STRING); + mv.visitMethodInsn(INVOKEVIRTUAL, InternalName.OBJECT, MethodName.EQUALS, + MethodDesc.EQUALS, false); // 如果不相等,跳转到下一个if判断,都不相等跳转到default defaultLabel mv.visitJumpInsn(IFEQ, i + 1 == fieldSize ? defaultLabel : ifLabels[i + 1]); mv.visitLabel(invokeLabels[i]);// 相等则调用get方法 - mv.visitVarInsn(ALOAD, LOCAL_VAR_INTERNAL_CLASS_INDEX); + mv.visitVarInsn(ALOAD, VarIndex.LOCAL_INTERNAL_CLASS); mv.visitMethodInsn(INVOKEVIRTUAL, internalClassName, curFieldDesc.readMethodName, curFieldDesc.readMethodDesc, false); addInvokeValueOfToPrimitive(mv, curFieldDesc.desc); @@ -398,43 +379,42 @@ class EnhanceClassGenerator implements Opcodes { } - private static void addInvokeValueOfToPrimitive(MethodVisitor mv, String returnTypeDesc) { - switch (returnTypeDesc) { - case TypeDescriptorConstants.INT_: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Integer", BeanEnhanceConstants.METHOD_VALUE_OF, - "(I)Ljava/lang/Integer;", false); - break; - case TypeDescriptorConstants.BOOLEAN_: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Boolean", BeanEnhanceConstants.METHOD_VALUE_OF, - "(Z)Ljava/lang/Boolean;", false); - break; - case TypeDescriptorConstants.BYTE_: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Byte", BeanEnhanceConstants.METHOD_VALUE_OF, - "(B)Ljava/lang/Byte;", false); - break; - case TypeDescriptorConstants.CHARACTER_: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Character", BeanEnhanceConstants.METHOD_VALUE_OF, - "(C)Ljava/lang/Character;", false); - break; - case TypeDescriptorConstants.SHORT_: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Short", BeanEnhanceConstants.METHOD_VALUE_OF, - "(S)Ljava/lang/Short;", false); - break; - case TypeDescriptorConstants.DOUBLE_: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Double", BeanEnhanceConstants.METHOD_VALUE_OF, - "(D)Ljava/lang/Double;", false); - break; - case TypeDescriptorConstants.FLOAT_: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Float", BeanEnhanceConstants.METHOD_VALUE_OF, - "(F)Ljava/lang/Float;", false); - break; - case TypeDescriptorConstants.LONG_: - mv.visitMethodInsn(INVOKESTATIC, "java/lang/Long", BeanEnhanceConstants.METHOD_VALUE_OF, - "(J)Ljava/lang/Long;", false); - break; + /** 用于在 {@see addInvokeValueOfToPrimitive } 方法中代替 {@code switch(returnTypeDesc)} 语句,可提高 33% 的性能 */ + private static final int HASH_CODE_INT = TypeDescriptor.INT.hashCode(); + private static final int HASH_CODE_BOOLEAN = TypeDescriptor.BOOLEAN.hashCode(); + private static final int HASH_CODE_BYTE = TypeDescriptor.BYTE.hashCode(); + private static final int HASH_CODE_CHAR = TypeDescriptor.CHAR.hashCode(); + private static final int HASH_CODE_SHORT = TypeDescriptor.SHORT.hashCode(); + private static final int HASH_CODE_DOUBLE = TypeDescriptor.DOUBLE.hashCode(); + private static final int HASH_CODE_FLOAT = TypeDescriptor.FLOAT.hashCode(); + private static final int HASH_CODE_LONG = TypeDescriptor.LONG.hashCode(); - default: - break; + /** + * 根据指定返回类型描述,添加 static 修饰的 'valueOf' 方法 + * + * @param mv asm 方法访问者 + * @param returnTypeDesc 返回类型描述 {@see Constants.TypeDescriptor} + */ + private static void addInvokeValueOfToPrimitive(MethodVisitor mv, String returnTypeDesc) { + int opcode = INVOKESTATIC; // static 方法调用 + String methodName = MethodName.VALUE_OF; // 方法名为 valueOf + int hashCode = returnTypeDesc.hashCode(); + if (hashCode == HASH_CODE_INT && TypeDescriptor.INT.equals(returnTypeDesc)) { + mv.visitMethodInsn(opcode, InternalName.INTEGER, methodName, MethodDesc.VALUE_OF_INTEGER, false); + } else if (hashCode == HASH_CODE_BOOLEAN && TypeDescriptor.BOOLEAN.equals(returnTypeDesc)) { + mv.visitMethodInsn(opcode, InternalName.BOOLEAN, methodName, MethodDesc.VALUE_OF_BOOLEAN, false); + } else if (hashCode == HASH_CODE_BYTE && TypeDescriptor.BYTE.equals(returnTypeDesc)) { + mv.visitMethodInsn(opcode, InternalName.BYTE, methodName, MethodDesc.VALUE_OF_BYTE, false); + } else if (hashCode == HASH_CODE_CHAR && TypeDescriptor.CHAR.equals(returnTypeDesc)) { + mv.visitMethodInsn(opcode, InternalName.CHARACTER, methodName, MethodDesc.VALUE_OF_CHARACTER, false); + } else if (hashCode == HASH_CODE_SHORT && TypeDescriptor.SHORT.equals(returnTypeDesc)) { + mv.visitMethodInsn(opcode, InternalName.SHORT, methodName, MethodDesc.VALUE_OF_SHORT, false); + } else if (hashCode == HASH_CODE_DOUBLE && TypeDescriptor.DOUBLE.equals(returnTypeDesc)) { + mv.visitMethodInsn(opcode, InternalName.DOUBLE, methodName, MethodDesc.VALUE_OF_DOUBLE, false); + } else if (hashCode == HASH_CODE_FLOAT && TypeDescriptor.FLOAT.equals(returnTypeDesc)) { + mv.visitMethodInsn(opcode, InternalName.FLOAT, methodName, MethodDesc.VALUE_OF_FLOAT, false); + } else if (hashCode == HASH_CODE_LONG && TypeDescriptor.LONG.equals(returnTypeDesc)) { + mv.visitMethodInsn(opcode, InternalName.LONG, methodName, MethodDesc.VALUE_OF_LONG, false); } } diff --git a/src/main/java/org/beetl/core/om/asm/FieldDescription.java b/src/main/java/org/beetl/core/om/asm/FieldDescription.java index 2fc1bbe0337f7faf92c28b5c62d109d8f21e85fd..760f6dd66b9993b21eda16448ebda2888f6b5e4b 100644 --- a/src/main/java/org/beetl/core/om/asm/FieldDescription.java +++ b/src/main/java/org/beetl/core/om/asm/FieldDescription.java @@ -1,25 +1,27 @@ package org.beetl.core.om.asm; +/** + * 字段描述信息 + */ class FieldDescription { + + /** 字段名称 */ String name; - /** - * The field's descriptor (see {@link org.objectweb.asm.Type}). - */ + /** 字段描述符 */ String desc; - /** - * getXXX - */ + /** getXXX */ String readMethodName; + /** 类似()I,(I)Ljava/lang/Integer; {@link org.beetl.ow2.asm.Type} */ + String readMethodDesc; + /** - * 类似()I,(I)Ljava/lang/Integer; + * 构造方法 * - * @see {@link org.objectweb.asm.Type} + * @param name 字段名称 + * @param desc 描述 + * @param readMethodName getXXX 方法名称 + * @param readMethodDesc getXXX 方法描述 */ - String readMethodDesc; - - public FieldDescription() { - } - public FieldDescription(String name, String desc, String readMethodName, String readMethodDesc) { super(); this.name = name; diff --git a/src/main/java/org/beetl/core/om/asm/MethodDescription.java b/src/main/java/org/beetl/core/om/asm/MethodDescription.java index f87d945995253846aae5d24b4b291e916b8ed5db..66c1ee82853424b0f9bbf12a76f9dc1bfa664c03 100644 --- a/src/main/java/org/beetl/core/om/asm/MethodDescription.java +++ b/src/main/java/org/beetl/core/om/asm/MethodDescription.java @@ -15,19 +15,27 @@ package org.beetl.core.om.asm; */ class MethodDescription { + /** 方法名称 */ String name; - - /** - * 类似(Ljava/lang/Object;)Ljava/lang/Object; - */ + /** 方法描述信息,例如 {@code (Ljava/lang/Object;)Ljava/lang/Object;} */ String desc; - /** - * 类似java/lang/Object - */ + /** 方法入参的内部名,例如 {@code java/lang/Object} */ String parameterInternalName; - /** - * 类似java/lang/Object - */ + /** 返回值的内部名,例如 {@code java/lang/Object} */ String returnTypeInternalName; + /** + * 构造方法 + * + * @param name 方法名称 + * @param desc 方法描述信息,例如 {@code (Ljava/lang/Object;)Ljava/lang/Object;} + * @param parameterInternalName 方法入参的内部名,例如 {@code java/lang/Object} + * @param returnTypeInternalName 返回值的内部名,例如 {@code java/lang/Object} + */ + MethodDescription(String name, String desc, String parameterInternalName, String returnTypeInternalName) { + this.name = name; + this.desc = desc; + this.parameterInternalName = parameterInternalName; + this.returnTypeInternalName = returnTypeInternalName; + } } diff --git a/src/main/java/org/beetl/core/om/asm/PunctuationConstants.java b/src/main/java/org/beetl/core/om/asm/PunctuationConstants.java deleted file mode 100644 index 0b0688484f613bf04d200a756b7755ba8be4e085..0000000000000000000000000000000000000000 --- a/src/main/java/org/beetl/core/om/asm/PunctuationConstants.java +++ /dev/null @@ -1,43 +0,0 @@ -package org.beetl.core.om.asm; - -/** - * 标点符号常量 - * - * @author laozhaishaozuo@foxmail.com - */ -public final class PunctuationConstants { - - private PunctuationConstants() { - - } - - /** - * 英文逗号:, - */ - public static final String COMMA = ","; - /** - * 英文百分号:% - */ - public static final String PERCENT = "%"; - /** - * 英文连字符:- - */ - public static final String HYPHEN = "-"; - /** - * 英文句点:. - */ - public static final String PERIOD = "."; - /** - * 英文句点:. - */ - public static final char PERIOD_CHAR = '.'; - /** - * 英文斜杆:/ - */ - public static final char SLASH_CHAR = '/'; - /** - * 英文左括号:( - */ - public static final char LEFT_BRACKET = '('; - -} diff --git a/src/main/java/org/beetl/core/om/asm/TypeDescriptorConstants.java b/src/main/java/org/beetl/core/om/asm/TypeDescriptorConstants.java deleted file mode 100644 index 57562a7c82ed62c96542d7cdfd1fe72dba01653c..0000000000000000000000000000000000000000 --- a/src/main/java/org/beetl/core/om/asm/TypeDescriptorConstants.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.beetl.core.om.asm; - -/** - * 类描述 - * - * @author laozhaishaozuo@foxmail.com - */ -public interface TypeDescriptorConstants { - String INT_ = "I"; - String VOID_ = "V"; - String BOOLEAN_ = "Z"; - String BYTE_ = "B"; - String CHARACTER_ = "C"; - String SHORT_ = "S"; - String DOUBLE_ = "D"; - String FLOAT_ = "F"; - String LONG_ = "J"; -} diff --git a/src/test/java/org/beetl/core/om/asm/ASMBeanFactoryTest.java b/src/test/java/org/beetl/core/om/asm/AsmBeanFactoryTest.java similarity index 91% rename from src/test/java/org/beetl/core/om/asm/ASMBeanFactoryTest.java rename to src/test/java/org/beetl/core/om/asm/AsmBeanFactoryTest.java index e87507b40f25f87f4b92fe21fc09379d37ec5327..45c98129507d6ad2d5979ca291ae020a7138a60b 100644 --- a/src/test/java/org/beetl/core/om/asm/ASMBeanFactoryTest.java +++ b/src/test/java/org/beetl/core/om/asm/AsmBeanFactoryTest.java @@ -8,7 +8,7 @@ import org.beetl.core.fun.ObjectUtil; import org.testng.AssertJUnit; import org.testng.annotations.Test; -public class ASMBeanFactoryTest extends BasicTestCase { +public class AsmBeanFactoryTest extends BasicTestCase { static User user = new User(); static { @@ -30,7 +30,7 @@ public class ASMBeanFactoryTest extends BasicTestCase { public void testAttrByAsm() throws Exception { boolean usePropertyDescriptor = false; ClassDescription classDescription = BeanEnhanceUtils.getClassDescription(User.class, usePropertyDescriptor); - ASMBeanFactory asmBeanFactory = new ASMBeanFactory(); + AsmBeanFactory asmBeanFactory = new AsmBeanFactory(); asmBeanFactory.setUsePropertyDescriptor(usePropertyDescriptor); for (List nodes : classDescription.fieldDescMap.values()) { for (FieldDescription node : nodes) { @@ -47,7 +47,7 @@ public class ASMBeanFactoryTest extends BasicTestCase { @Test public void testByProp() throws Exception { ClassDescription classDescription = BeanEnhanceUtils.getClassDescription(User.class, true); - ASMBeanFactory asmBeanFactory = new ASMBeanFactory(); + AsmBeanFactory asmBeanFactory = new AsmBeanFactory(); asmBeanFactory.setUsePropertyDescriptor(true); for (List nodes : classDescription.fieldDescMap.values()) { for (FieldDescription node : nodes) { @@ -65,7 +65,7 @@ public class ASMBeanFactoryTest extends BasicTestCase { @Test public void testOnlyGet() throws Exception { OnlyGet onlyGet = new OnlyGet(); - ASMBeanFactory asmBeanFactory = new ASMBeanFactory(); + AsmBeanFactory asmBeanFactory = new AsmBeanFactory(); AssertJUnit.assertEquals("哈哈是", asmBeanFactory.value(onlyGet, "填写")); AssertJUnit.assertEquals("哈哈是", asmBeanFactory.value(onlyGet, "写")); AssertJUnit.assertEquals("哈哈是", asmBeanFactory.value(onlyGet, "填")); @@ -74,7 +74,7 @@ public class ASMBeanFactoryTest extends BasicTestCase { @Test public void testOnlyGetString() throws Exception { OnlyGetString onlyGetStr = new OnlyGetString(); - ASMBeanFactory asmBeanFactory = new ASMBeanFactory(); + AsmBeanFactory asmBeanFactory = new AsmBeanFactory(); AssertJUnit.assertEquals("哈哈是", asmBeanFactory.value(onlyGetStr, "填写")); AssertJUnit.assertEquals("哈哈是", asmBeanFactory.value(onlyGetStr, "写")); AssertJUnit.assertEquals("哈哈是", asmBeanFactory.value(onlyGetStr, "cs")); @@ -84,7 +84,7 @@ public class ASMBeanFactoryTest extends BasicTestCase { public void testEmpty() throws Exception { String name = "zhangsan"; TestObject empty = new TestObject(name); - ASMBeanFactory asmBeanFactory = new ASMBeanFactory(); + AsmBeanFactory asmBeanFactory = new AsmBeanFactory(); try { asmBeanFactory.value(empty, "ss"); AssertJUnit.fail();