diff --git a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java index 86775de481..5d598ea998 100644 --- a/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java +++ b/dubbo-filter/dubbo-filter-validation/src/main/java/org/apache/dubbo/validation/support/jvalidation/JValidator.java @@ -119,8 +119,41 @@ public class JValidator implements Validator { try { parameterClass = Class.forName(parameterClassName, true, clazz.getClassLoader()); } catch (ClassNotFoundException e) { - ClassPool pool = ClassGenerator.getClassPool(clazz.getClassLoader()); - CtClass ctClass = pool.makeClass(parameterClassName); + parameterClass = generateMethodParameterClass(clazz, method, parameterClassName); + } + Object parameterBean = parameterClass.newInstance(); + for (int i = 0; i < args.length; i++) { + Field field = parameterClass.getField(method.getName() + "Argument" + i); + field.set(parameterBean, args[i]); + } + return parameterBean; + } catch (Throwable e) { + logger.warn(e.getMessage(), e); + return null; + } + } + + /** + * try to generate methodParameterClass. + * + * @param clazz interface class + * @param method invoke method + * @param parameterClassName generated parameterClassName + * @return Class generated methodParameterClass + * @throws Exception + */ + private static Class generateMethodParameterClass(Class clazz, Method method, String parameterClassName) + throws Exception { + ClassPool pool = ClassGenerator.getClassPool(clazz.getClassLoader()); + synchronized (parameterClassName.intern()) { + CtClass ctClass = null; + try { + ctClass = pool.getCtClass(parameterClassName); + } catch (NotFoundException ignore) { + } + + if (null == ctClass) { + ctClass = pool.makeClass(parameterClassName); ClassFile classFile = ctClass.getClassFile(); classFile.setVersionToJava5(); ctClass.addConstructor(CtNewConstructor.defaultConstructor(pool.getCtClass(parameterClassName))); @@ -134,16 +167,16 @@ public class JValidator implements Validator { for (Annotation annotation : annotations) { if (annotation.annotationType().isAnnotationPresent(Constraint.class)) { javassist.bytecode.annotation.Annotation ja = new javassist.bytecode.annotation.Annotation( - classFile.getConstPool(), pool.getCtClass(annotation.annotationType().getName())); + classFile.getConstPool(), pool.getCtClass(annotation.annotationType().getName())); Method[] members = annotation.annotationType().getMethods(); for (Method member : members) { if (Modifier.isPublic(member.getModifiers()) - && member.getParameterTypes().length == 0 - && member.getDeclaringClass() == annotation.annotationType()) { + && member.getParameterTypes().length == 0 + && member.getDeclaringClass() == annotation.annotationType()) { Object value = member.invoke(annotation); if (null != value) { MemberValue memberValue = createMemberValue( - classFile.getConstPool(), pool.get(member.getReturnType().getName()), value); + classFile.getConstPool(), pool.get(member.getReturnType().getName()), value); ja.addMemberValue(member.getName(), memberValue); } } @@ -156,17 +189,10 @@ public class JValidator implements Validator { ctField.getFieldInfo().addAttribute(attribute); ctClass.addField(ctField); } - parameterClass = ctClass.toClass(clazz.getClassLoader(), null); + return ctClass.toClass(clazz.getClassLoader(), null); + } else { + return Class.forName(parameterClassName, true, clazz.getClassLoader()); } - Object parameterBean = parameterClass.newInstance(); - for (int i = 0; i < args.length; i++) { - Field field = parameterClass.getField(method.getName() + "Argument" + i); - field.set(parameterBean, args[i]); - } - return parameterBean; - } catch (Throwable e) { - logger.warn(e.getMessage(), e); - return null; } }