class ClassUtils extends org.springframework.util.ClassUtils {

	private final ParameterNameDiscoverer PARAMETERNAMEDISCOVERER = new DefaultParameterNameDiscoverer();

	/**
	 * 获取方法参数信息
	 * @param constructor 构造器
	 * @param parameterIndex 参数序号
	 * @return {MethodParameter}
	 */
	public MethodParameter getMethodParameter(Constructor<?> constructor, int parameterIndex) {
		MethodParameter methodParameter = new SynthesizingMethodParameter(constructor, parameterIndex);
		methodParameter.initParameterNameDiscovery(PARAMETERNAMEDISCOVERER);
		return methodParameter;
	}

	/**
	 * 获取方法参数信息
	 * @param method 方法
	 * @param parameterIndex 参数序号
	 * @return {MethodParameter}
	 */
	public MethodParameter getMethodParameter(Method method, int parameterIndex) {
		MethodParameter methodParameter = new SynthesizingMethodParameter(method, parameterIndex);
		methodParameter.initParameterNameDiscovery(PARAMETERNAMEDISCOVERER);
		return methodParameter;
	}

	/**
	 * 获取Annotation
	 * @param method Method
	 * @param annotationType 注解类
	 * @param <A> 泛型标记
	 * @return {Annotation}
	 */
	public <A extends Annotation> A getAnnotation(Method method, Class<A> annotationType) {<FILL_FUNCTION_BODY>}

	/**
	 * 获取Annotation
	 * @param handlerMethod HandlerMethod
	 * @param annotationType 注解类
	 * @param <A> 泛型标记
	 * @return {Annotation}
	 */
	public <A extends Annotation> A getAnnotation(HandlerMethod handlerMethod, Class<A> annotationType) {
		// 先找方法，再找方法上的类
		A annotation = handlerMethod.getMethodAnnotation(annotationType);
		if (null != annotation) {
			return annotation;
		}
		// 获取类上面的Annotation，可能包含组合注解，故采用spring的工具类
		Class<?> beanType = handlerMethod.getBeanType();
		return AnnotatedElementUtils.findMergedAnnotation(beanType, annotationType);
	}

}

		Class<?> targetClass = method.getDeclaringClass();
		// The method may be on an interface, but we need attributes from the target
		// class.
		// If the target class is null, the method will be unchanged.
		Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
		// If we are dealing with method with generic parameters, find the original
		// method.
		specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
		// 先找方法，再找方法上的类
		A annotation = AnnotatedElementUtils.findMergedAnnotation(specificMethod, annotationType);
		;
		if (null != annotation) {
			return annotation;
		}
		// 获取类上面的Annotation，可能包含组合注解，故采用spring的工具类
		return AnnotatedElementUtils.findMergedAnnotation(specificMethod.getDeclaringClass(), annotationType);
	
<methods>public void <init>() ,public static java.lang.String addResourcePathToPackagePath(Class<?>, java.lang.String) ,public static transient java.lang.String classNamesToString(Class<?>[]) ,public static java.lang.String classNamesToString(Collection<Class<?>>) ,public static java.lang.String classPackageAsResourcePath(Class<?>) ,public static java.lang.String convertClassNameToResourcePath(java.lang.String) ,public static java.lang.String convertResourcePathToClassName(java.lang.String) ,public static Class<?> createCompositeInterface(Class<?>[], java.lang.ClassLoader) ,public static Class<?> determineCommonAncestor(Class<?>, Class<?>) ,public static Class<?> forName(java.lang.String, java.lang.ClassLoader) throws java.lang.ClassNotFoundException, java.lang.LinkageError,public static Class<?>[] getAllInterfaces(java.lang.Object) ,public static Set<Class<?>> getAllInterfacesAsSet(java.lang.Object) ,public static Class<?>[] getAllInterfacesForClass(Class<?>) ,public static Class<?>[] getAllInterfacesForClass(Class<?>, java.lang.ClassLoader) ,public static Set<Class<?>> getAllInterfacesForClassAsSet(Class<?>) ,public static Set<Class<?>> getAllInterfacesForClassAsSet(Class<?>, java.lang.ClassLoader) ,public static java.lang.String getClassFileName(Class<?>) ,public static transient Constructor<T> getConstructorIfAvailable(Class<T>, Class<?>[]) ,public static java.lang.ClassLoader getDefaultClassLoader() ,public static java.lang.String getDescriptiveType(java.lang.Object) ,public static java.lang.reflect.Method getInterfaceMethodIfPossible(java.lang.reflect.Method) ,public static java.lang.reflect.Method getInterfaceMethodIfPossible(java.lang.reflect.Method, Class<?>) ,public static transient java.lang.reflect.Method getMethod(Class<?>, java.lang.String, Class<?>[]) ,public static int getMethodCountForName(Class<?>, java.lang.String) ,public static transient java.lang.reflect.Method getMethodIfAvailable(Class<?>, java.lang.String, Class<?>[]) ,public static java.lang.reflect.Method getMostSpecificMethod(java.lang.reflect.Method, Class<?>) ,public static java.lang.String getPackageName(Class<?>) ,public static java.lang.String getPackageName(java.lang.String) ,public static java.lang.String getQualifiedMethodName(java.lang.reflect.Method) ,public static java.lang.String getQualifiedMethodName(java.lang.reflect.Method, Class<?>) ,public static java.lang.String getQualifiedName(Class<?>) ,public static java.lang.String getShortName(java.lang.String) ,public static java.lang.String getShortName(Class<?>) ,public static java.lang.String getShortNameAsProperty(Class<?>) ,public static transient java.lang.reflect.Method getStaticMethod(Class<?>, java.lang.String, Class<?>[]) ,public static Class<?> getUserClass(java.lang.Object) ,public static Class<?> getUserClass(Class<?>) ,public static boolean hasAtLeastOneMethodWithName(Class<?>, java.lang.String) ,public static transient boolean hasConstructor(Class<?>, Class<?>[]) ,public static boolean hasMethod(Class<?>, java.lang.reflect.Method) ,public static transient boolean hasMethod(Class<?>, java.lang.String, Class<?>[]) ,public static boolean isAssignable(Class<?>, Class<?>) ,public static boolean isAssignableValue(Class<?>, java.lang.Object) ,public static boolean isCacheSafe(Class<?>, java.lang.ClassLoader) ,public static boolean isCglibProxy(java.lang.Object) ,public static boolean isCglibProxyClass(Class<?>) ,public static boolean isCglibProxyClassName(java.lang.String) ,public static boolean isInnerClass(Class<?>) ,public static boolean isJavaLanguageInterface(Class<?>) ,public static boolean isLambdaClass(Class<?>) ,public static boolean isPresent(java.lang.String, java.lang.ClassLoader) ,public static boolean isPrimitiveArray(Class<?>) ,public static boolean isPrimitiveOrWrapper(Class<?>) ,public static boolean isPrimitiveWrapper(Class<?>) ,public static boolean isPrimitiveWrapperArray(Class<?>) ,public static boolean isSimpleValueType(Class<?>) ,public static boolean isStaticClass(Class<?>) ,public static boolean isUserLevelMethod(java.lang.reflect.Method) ,public static boolean isVisible(Class<?>, java.lang.ClassLoader) ,public static boolean isVoidType(Class<?>) ,public static boolean matchesTypeName(Class<?>, java.lang.String) ,public static java.lang.ClassLoader overrideThreadContextClassLoader(java.lang.ClassLoader) ,public static Class<?> resolveClassName(java.lang.String, java.lang.ClassLoader) throws java.lang.IllegalArgumentException,public static Class<?> resolvePrimitiveClassName(java.lang.String) ,public static Class<?> resolvePrimitiveIfNecessary(Class<?>) ,public static Class<?>[] toClassArray(Collection<Class<?>>) <variables>public static final java.lang.String ARRAY_SUFFIX,public static final java.lang.String CGLIB_CLASS_SEPARATOR,public static final java.lang.String CLASS_FILE_SUFFIX,private static final Class<?>[] EMPTY_CLASS_ARRAY,private static final java.lang.String INTERNAL_ARRAY_PREFIX,private static final char NESTED_CLASS_SEPARATOR,private static final int NON_OVERRIDABLE_MODIFIER,private static final java.lang.String NON_PRIMITIVE_ARRAY_PREFIX,private static final int OVERRIDABLE_MODIFIER,private static final char PACKAGE_SEPARATOR,private static final char PATH_SEPARATOR,private static final Map<java.lang.String,Class<?>> commonClassCache,private static final Map<java.lang.reflect.Method,java.lang.reflect.Method> interfaceMethodCache,private static final Set<Class<?>> javaLanguageInterfaces,private static final Map<java.lang.String,Class<?>> primitiveTypeNameMap,private static final Map<Class<?>,Class<?>> primitiveTypeToWrapperMap,private static final Map<Class<?>,Class<?>> primitiveWrapperTypeMap