一、前言
关于hudson-core源码中hudson.util.ReflectionUtils工具类,集成spring的org.springframework.util.ReflectionUtils类重写并实现获取公共静态方法getPublicMethodNamed、获取静态公共属性getPublicProperty等。
二、源码说明
package hudson.util;@b@@b@import org.apache.commons.beanutils.PropertyUtils;@b@import org.kohsuke.stapler.ClassDescriptor; @b@import java.beans.PropertyDescriptor;@b@import java.lang.annotation.Annotation;@b@import java.lang.reflect.Field;@b@import java.lang.reflect.InvocationTargetException;@b@import java.lang.reflect.Method;@b@import java.lang.reflect.Type;@b@import java.util.AbstractList;@b@import java.util.HashMap;@b@import java.util.List;@b@import java.util.Map;@b@@b@ @b@public class ReflectionUtils extends org.springframework.util.ReflectionUtils {@b@ @b@ public static Method getPublicMethodNamed(Class c, String methodName) {@b@ for( Method m : c.getMethods() )@b@ if(m.getName().equals(methodName))@b@ return m;@b@ return null;@b@ }@b@@b@ @b@ public static List<Parameter> getParameters(Method m) {@b@ return new MethodInfo(m);@b@ }@b@@b@ public static Object getPublicProperty(Object o, String p) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {@b@ PropertyDescriptor pd = PropertyUtils.getPropertyDescriptor(o, p);@b@ if(pd==null) {@b@ // field?@b@ try {@b@ Field f = o.getClass().getField(p);@b@ return f.get(o);@b@ } catch (NoSuchFieldException e) {@b@ throw new IllegalArgumentException("No such property "+p+" on "+o.getClass());@b@ }@b@ } else {@b@ return PropertyUtils.getProperty(o, p);@b@ }@b@ }@b@@b@ @b@ private static final class MethodInfo extends AbstractList<Parameter> {@b@ private final Method method;@b@ private final Class<?>[] types;@b@ private Type[] genericTypes;@b@ private Annotation[][] annotations;@b@ private String[] names;@b@@b@ private MethodInfo(Method method) {@b@ this.method = method;@b@ types = method.getParameterTypes();@b@ }@b@@b@ @Override@b@ public Parameter get(int index) {@b@ return new Parameter(this,index);@b@ }@b@@b@ @Override@b@ public int size() {@b@ return types.length;@b@ }@b@@b@ public Type[] genericTypes() {@b@ if (genericTypes==null)@b@ genericTypes = method.getGenericParameterTypes();@b@ return genericTypes;@b@ }@b@@b@ public Annotation[][] annotations() {@b@ if (annotations==null)@b@ annotations = method.getParameterAnnotations();@b@ return annotations;@b@ }@b@@b@ public String[] names() {@b@ if (names==null)@b@ names = ClassDescriptor.loadParameterNames(method);@b@ return names;@b@ }@b@ }@b@@b@ public static final class Parameter {@b@ private final MethodInfo parent;@b@ private final int index;@b@@b@ public Parameter(MethodInfo parent, int index) {@b@ this.parent = parent;@b@ this.index = index;@b@ }@b@@b@ /**@b@ * 0-origin index of this parameter.@b@ */@b@ public int index() {@b@ return index;@b@ }@b@@b@ /**@b@ * Gets the type of this parameter.@b@ */@b@ public Class<?> type() {@b@ return parent.types[index];@b@ }@b@@b@ /**@b@ * Gets the unerased generic type of this parameter.@b@ */@b@ public Type genericType() {@b@ return parent.genericTypes()[index];@b@ }@b@@b@ /**@b@ * Gets all the annotations on this parameter.@b@ */@b@ public Annotation[] annotations() {@b@ return parent.annotations()[index];@b@ }@b@@b@ /**@b@ * Gets the specified annotation on this parameter or null.@b@ */@b@ public <A extends Annotation> A annotation(Class<A> type) {@b@ for (Annotation a : annotations())@b@ if (a.annotationType()==type)@b@ return type.cast(a);@b@ return null;@b@ }@b@@b@ /**@b@ * Name of this parameter.@b@ *@b@ * If unknown, this method returns null.@b@ */@b@ public String name() {@b@ String[] names = parent.names();@b@ if (index<names.length)@b@ return names[index];@b@ return null;@b@ }@b@ }@b@@b@ /**@b@ * Given the primitive type, returns the VM default value for that type in a boxed form.@b@ */@b@ public static Object getVmDefaultValueForPrimitiveType(Class<?> type) {@b@ return defaultPrimitiveValue.get(type);@b@ }@b@@b@ private static final Map<Class,Object> defaultPrimitiveValue = new HashMap<Class, Object>();@b@ static {@b@ defaultPrimitiveValue.put(boolean.class,false);@b@ defaultPrimitiveValue.put(int.class,0);@b@ defaultPrimitiveValue.put(long.class,0L);@b@ }@b@}