From 2c8b7fe0935a5934d7b6357086b17f3ac45cb66c Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 26 Sep 2012 20:04:43 +0200 Subject: [PATCH] ClassUtils.getMostSpecificMethod uses Class.getMethod code path in case of a public method This should be significantly faster than our standard algorithm, for a very common case. Motivated by SPR-9802, even if the fix there uses a different approach, with transaction name determination not calling getMostSpecificMethod at all anymore. Issue: SPR-9802 --- .../org/springframework/util/ClassUtils.java | 49 +++++++++++++------ 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/org.springframework.core/src/main/java/org/springframework/util/ClassUtils.java b/org.springframework.core/src/main/java/org/springframework/util/ClassUtils.java index cbd6bae5801..6def0062324 100644 --- a/org.springframework.core/src/main/java/org/springframework/util/ClassUtils.java +++ b/org.springframework.core/src/main/java/org/springframework/util/ClassUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2011 the original author or authors. + * Copyright 2002-2012 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -462,17 +462,28 @@ public abstract class ClassUtils { } /** - * Determine the name of the package of the given class: - * e.g. "java.lang" for the java.lang.String class. + * Determine the name of the package of the given class, + * e.g. "java.lang" for the {@code java.lang.String} class. * @param clazz the class * @return the package name, or the empty String if the class * is defined in the default package */ public static String getPackageName(Class clazz) { Assert.notNull(clazz, "Class must not be null"); - String className = clazz.getName(); - int lastDotIndex = className.lastIndexOf(PACKAGE_SEPARATOR); - return (lastDotIndex != -1 ? className.substring(0, lastDotIndex) : ""); + return getPackageName(clazz.getName()); + } + + /** + * Determine the name of the package of the given fully-qualified class name, + * e.g. "java.lang" for the {@code java.lang.String} class name. + * @param fqClassName the fully-qualified class name + * @return the package name, or the empty String if the class + * is defined in the default package + */ + public static String getPackageName(String fqClassName) { + Assert.notNull(fqClassName, "Class name must not be null"); + int lastDotIndex = fqClassName.lastIndexOf(PACKAGE_SEPARATOR); + return (lastDotIndex != -1 ? fqClassName.substring(0, lastDotIndex) : ""); } /** @@ -713,7 +724,7 @@ public abstract class ClassUtils { * Call {@link org.springframework.core.BridgeMethodResolver#findBridgedMethod} * if bridge method resolution is desirable (e.g. for obtaining metadata from * the original method definition). - *

NOTE:Since Spring 3.1.1, if java security settings disallow reflective + *

NOTE: Since Spring 3.1.1, if Java security settings disallow reflective * access (e.g. calls to {@code Class#getDeclaredMethods} etc, this implementation * will fall back to returning the originally provided method. * @param method the method to be invoked, which may come from an interface @@ -723,17 +734,28 @@ public abstract class ClassUtils { * targetClass doesn't implement it or is null */ public static Method getMostSpecificMethod(Method method, Class targetClass) { - Method specificMethod = null; if (method != null && isOverridable(method, targetClass) && targetClass != null && !targetClass.equals(method.getDeclaringClass())) { try { - specificMethod = ReflectionUtils.findMethod(targetClass, method.getName(), method.getParameterTypes()); - } catch (AccessControlException ex) { - // security settings are disallowing reflective access; leave - // 'specificMethod' null and fall back to 'method' below + if (Modifier.isPublic(method.getModifiers())) { + try { + return targetClass.getMethod(method.getName(), method.getParameterTypes()); + } + catch (NoSuchMethodException ex) { + return method; + } + } + else { + Method specificMethod = + ReflectionUtils.findMethod(targetClass, method.getName(), method.getParameterTypes()); + return (specificMethod != null ? specificMethod : method); + } + } + catch (AccessControlException ex) { + // Security settings are disallowing reflective access; fall back to 'method' below. } } - return (specificMethod != null ? specificMethod : method); + return method; } /** @@ -1139,5 +1161,4 @@ public abstract class ClassUtils { return (className != null && className.contains(CGLIB_CLASS_SEPARATOR)); } - }