一、前言
关于spring的spring-test源码包中org.springframework.test.util.ReflectionTestUtils反射测试工具类,对org.springframework.util.ReflectionUtils反射工具类进行用例代码测试说明,详情参见源码说明部分。
二、源码说明
package org.springframework.test.util;@b@@b@import java.lang.reflect.Field;@b@import java.lang.reflect.Method;@b@import org.apache.commons.logging.Log;@b@import org.apache.commons.logging.LogFactory;@b@import org.springframework.util.Assert;@b@import org.springframework.util.ClassUtils;@b@import org.springframework.util.MethodInvoker;@b@import org.springframework.util.ObjectUtils;@b@import org.springframework.util.ReflectionUtils;@b@import org.springframework.util.StringUtils;@b@@b@public abstract class ReflectionTestUtils@b@{@b@ private static final String SETTER_PREFIX = "set";@b@ private static final String GETTER_PREFIX = "get";@b@ private static final Log logger = LogFactory.getLog(ReflectionTestUtils.class);@b@ private static final boolean springAopPresent = ClassUtils.isPresent("org.springframework.aop.framework.Advised", ReflectionTestUtils.class@b@ .getClassLoader());@b@@b@ public static void setField(Object targetObject, String name, Object value)@b@ {@b@ setField(targetObject, name, value, null);@b@ }@b@@b@ public static void setField(Object targetObject, String name, Object value, Class<?> type)@b@ {@b@ setField(targetObject, null, name, value, type);@b@ }@b@@b@ public static void setField(Class<?> targetClass, String name, Object value)@b@ {@b@ setField(null, targetClass, name, value, null);@b@ }@b@@b@ public static void setField(Class<?> targetClass, String name, Object value, Class<?> type)@b@ {@b@ setField(null, targetClass, name, value, type);@b@ }@b@@b@ public static void setField(Object targetObject, Class<?> targetClass, String name, Object value, Class<?> type)@b@ {@b@ Assert.isTrue((targetObject != null) || (targetClass != null), "Either targetObject or targetClass for the field must be specified");@b@@b@ if ((targetObject != null) && (springAopPresent))@b@ targetObject = AopTestUtils.getUltimateTargetObject(targetObject);@b@@b@ if (targetClass == null) {@b@ targetClass = targetObject.getClass();@b@ }@b@@b@ Field field = ReflectionUtils.findField(targetClass, name, type);@b@ if (field == null) {@b@ throw new IllegalArgumentException(String.format("Could not find field '%s' of type [%s] on %s or target class [%s]", new Object[] { name, type, @b@ safeToString(targetObject), @b@ targetClass }));@b@ }@b@@b@ if (logger.isDebugEnabled())@b@ logger.debug(String.format("Setting field '%s' of type [%s] on %s or target class [%s] to value [%s]", new Object[] { name, type, @b@ safeToString(targetObject), @b@ targetClass, value }));@b@@b@ ReflectionUtils.makeAccessible(field);@b@ ReflectionUtils.setField(field, targetObject, value);@b@ }@b@@b@ public static Object getField(Object targetObject, String name)@b@ {@b@ return getField(targetObject, null, name);@b@ }@b@@b@ public static Object getField(Class<?> targetClass, String name)@b@ {@b@ return getField(null, targetClass, name);@b@ }@b@@b@ public static Object getField(Object targetObject, Class<?> targetClass, String name)@b@ {@b@ Assert.isTrue((targetObject != null) || (targetClass != null), "Either targetObject or targetClass for the field must be specified");@b@@b@ if ((targetObject != null) && (springAopPresent))@b@ targetObject = AopTestUtils.getUltimateTargetObject(targetObject);@b@@b@ if (targetClass == null) {@b@ targetClass = targetObject.getClass();@b@ }@b@@b@ Field field = ReflectionUtils.findField(targetClass, name);@b@ if (field == null) {@b@ throw new IllegalArgumentException(String.format("Could not find field '%s' on %s or target class [%s]", new Object[] { name, @b@ safeToString(targetObject), @b@ targetClass }));@b@ }@b@@b@ if (logger.isDebugEnabled())@b@ logger.debug(String.format("Getting field '%s' from %s or target class [%s]", new Object[] { name, @b@ safeToString(targetObject), @b@ targetClass }));@b@@b@ ReflectionUtils.makeAccessible(field);@b@ return ReflectionUtils.getField(field, targetObject);@b@ }@b@@b@ public static void invokeSetterMethod(Object target, String name, Object value)@b@ {@b@ invokeSetterMethod(target, name, value, null); } @b@ public static void invokeSetterMethod(Object target, String name, Object value, Class<?> type) { // Byte code:@b@ // 0: aload_0@b@ // 1: ldc 28@b@ // 3: invokestatic 29 org/springframework/util/Assert:notNull (Ljava/lang/Object;Ljava/lang/String;)V@b@ // 6: aload_1@b@ // 7: ldc 30@b@ // 9: invokestatic 31 org/springframework/util/Assert:hasText (Ljava/lang/String;Ljava/lang/String;)V@b@ // 12: aload_3@b@ // 13: ifnull +14 -> 27@b@ // 16: iconst_1@b@ // 17: anewarray 32 java/lang/Class@b@ // 20: dup@b@ // 21: iconst_0@b@ // 22: aload_3@b@ // 23: aastore@b@ // 24: goto +4 -> 28@b@ // 27: aconst_null@b@ // 28: astore 4@b@ // 30: aload_1@b@ // 31: astore 5@b@ // 33: aload_1@b@ // 34: ldc 34@b@ // 36: invokevirtual 35 java/lang/String:startsWith (Ljava/lang/String;)Z@b@ // 39: ifne +27 -> 66@b@ // 42: new 36 java/lang/StringBuilder@b@ // 45: dup@b@ // 46: invokespecial 37 java/lang/StringBuilder:<init> ()V@b@ // 49: ldc 34@b@ // 51: invokevirtual 38 java/lang/StringBuilder:append (Ljava/lang/String;)Ljava/lang/StringBuilder;@b@ // 54: aload_1@b@ // 55: invokestatic 39 org/springframework/util/StringUtils:capitalize (Ljava/lang/String;)Ljava/lang/String;@b@ // 58: invokevirtual 38 java/lang/StringBuilder:append (Ljava/lang/String;)Ljava/lang/StringBuilder;@b@ // 61: invokevirtual 40 java/lang/StringBuilder:toString ()Ljava/lang/String;@b@ // 64: astore 5@b@ // 66: aload_0@b@ // 67: invokevirtual 8 java/lang/Object:getClass ()Ljava/lang/Class;@b@ // 70: aload 5@b@ // 72: aload 4@b@ // 74: invokestatic 41 org/springframework/util/ReflectionUtils:findMethod (Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;@b@ // 77: astore 6@b@ // 79: aload 6@b@ // 81: ifnonnull +28 -> 109@b@ // 84: aload 5@b@ // 86: aload_1@b@ // 87: invokevirtual 42 java/lang/String:equals (Ljava/lang/Object;)Z@b@ // 90: ifne +19 -> 109@b@ // 93: aload_1@b@ // 94: astore 5@b@ // 96: aload_0@b@ // 97: invokevirtual 8 java/lang/Object:getClass ()Ljava/lang/Class;@b@ // 100: aload 5@b@ // 102: aload 4@b@ // 104: invokestatic 41 org/springframework/util/ReflectionUtils:findMethod (Ljava/lang/Class;Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;@b@ // 107: astore 6@b@ // 109: aload 6@b@ // 111: ifnonnull +36 -> 147@b@ // 114: new 10 java/lang/IllegalArgumentException@b@ // 117: dup@b@ // 118: ldc 43@b@ // 120: iconst_3@b@ // 121: anewarray 12 java/lang/Object@b@ // 124: dup@b@ // 125: iconst_0@b@ // 126: aload 5@b@ // 128: aastore@b@ // 129: dup@b@ // 130: iconst_1@b@ // 131: aload_0@b@ // 132: invokestatic 13 org/springframework/test/util/ReflectionTestUtils:safeToString (Ljava/lang/Object;)Ljava/lang/String;@b@ // 135: aastore@b@ // 136: dup@b@ // 137: iconst_2@b@ // 138: aload_3@b@ // 139: aastore@b@ // 140: invokestatic 14 java/lang/String:format (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;@b@ // 143: invokespecial 15 java/lang/IllegalArgumentException:<init> (Ljava/lang/String;)V@b@ // 146: athrow@b@ // 147: getstatic 16 org/springframework/test/util/ReflectionTestUtils:logger Lorg/apache/commons/logging/Log;@b@ // 150: invokeinterface 17 1 0@b@ // 155: ifeq +36 -> 191@b@ // 158: getstatic 16 org/springframework/test/util/ReflectionTestUtils:logger Lorg/apache/commons/logging/Log;@b@ // 161: ldc 44@b@ // 163: iconst_3@b@ // 164: anewarray 12 java/lang/Object@b@ // 167: dup@b@ // 168: iconst_0@b@ // 169: aload 5@b@ // 171: aastore@b@ // 172: dup@b@ // 173: iconst_1@b@ // 174: aload_0@b@ // 175: invokestatic 13 org/springframework/test/util/ReflectionTestUtils:safeToString (Ljava/lang/Object;)Ljava/lang/String;@b@ // 178: aastore@b@ // 179: dup@b@ // 180: iconst_2@b@ // 181: aload_2@b@ // 182: aastore@b@ // 183: invokestatic 14 java/lang/String:format (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;@b@ // 186: invokeinterface 19 2 0@b@ // 191: aload 6@b@ // 193: invokestatic 45 org/springframework/util/ReflectionUtils:makeAccessible (Ljava/lang/reflect/Method;)V@b@ // 196: aload 6@b@ // 198: aload_0@b@ // 199: iconst_1@b@ // 200: anewarray 12 java/lang/Object@b@ // 203: dup@b@ // 204: iconst_0@b@ // 205: aload_2@b@ // 206: aastore@b@ // 207: invokestatic 46 org/springframework/util/ReflectionUtils:invokeMethod (Ljava/lang/reflect/Method;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;@b@ // 210: pop@b@ // 211: return } @b@ public static Object invokeGetterMethod(Object target, String name) { Assert.notNull(target, "Target object must not be null");@b@ Assert.hasText(name, "Method name must not be empty");@b@@b@ String getterMethodName = name;@b@ if (!(name.startsWith("get")))@b@ getterMethodName = "get" + StringUtils.capitalize(name);@b@@b@ Method method = ReflectionUtils.findMethod(target.getClass(), getterMethodName);@b@ if ((method == null) && (!(getterMethodName.equals(name)))) {@b@ getterMethodName = name;@b@ method = ReflectionUtils.findMethod(target.getClass(), getterMethodName);@b@ }@b@ if (method == null) {@b@ throw new IllegalArgumentException(String.format("Could not find getter method '%s' on %s", new Object[] { getterMethodName, @b@ safeToString(target) }));@b@ }@b@@b@ if (logger.isDebugEnabled())@b@ logger.debug(String.format("Invoking getter method '%s' on %s", new Object[] { getterMethodName, safeToString(target) }));@b@@b@ ReflectionUtils.makeAccessible(method);@b@ return ReflectionUtils.invokeMethod(method, target);@b@ }@b@@b@ public static <T> T invokeMethod(Object target, String name, Object[] args)@b@ {@b@ Assert.notNull(target, "Target object must not be null");@b@ Assert.hasText(name, "Method name must not be empty");@b@ try@b@ {@b@ MethodInvoker methodInvoker = new MethodInvoker();@b@ methodInvoker.setTargetObject(target);@b@ methodInvoker.setTargetMethod(name);@b@ methodInvoker.setArguments(args);@b@ methodInvoker.prepare();@b@@b@ if (logger.isDebugEnabled()) {@b@ logger.debug(String.format("Invoking method '%s' on %s with arguments %s", new Object[] { name, safeToString(target), @b@ ObjectUtils.nullSafeToString(args) }));@b@ }@b@@b@ return methodInvoker.invoke();@b@ }@b@ catch (Exception ex) {@b@ ReflectionUtils.handleReflectionException(ex);@b@ throw new IllegalStateException("Should never get here");@b@ }@b@ }@b@@b@ private static String safeToString(Object target)@b@ {@b@ // Byte code:@b@ // 0: ldc 66@b@ // 2: iconst_1@b@ // 3: anewarray 12 java/lang/Object@b@ // 6: dup@b@ // 7: iconst_0@b@ // 8: aload_0@b@ // 9: aastore@b@ // 10: invokestatic 14 java/lang/String:format (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;@b@ // 13: areturn@b@ // 14: astore_1@b@ // 15: ldc 67@b@ // 17: iconst_2@b@ // 18: anewarray 12 java/lang/Object@b@ // 21: dup@b@ // 22: iconst_0@b@ // 23: aload_0@b@ // 24: ifnull +13 -> 37@b@ // 27: aload_0@b@ // 28: invokevirtual 8 java/lang/Object:getClass ()Ljava/lang/Class;@b@ // 31: invokevirtual 68 java/lang/Class:getName ()Ljava/lang/String;@b@ // 34: goto +5 -> 39@b@ // 37: ldc 69@b@ // 39: aastore@b@ // 40: dup@b@ // 41: iconst_1@b@ // 42: aload_1@b@ // 43: aastore@b@ // 44: invokestatic 14 java/lang/String:format (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;@b@ // 47: areturn@b@ //@b@ // Exception table:@b@ // from to target type@b@ // 0 13 14 java/lang/Exception@b@ }@b@}