You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@dubbo.apache.org by il...@apache.org on 2019/08/20 06:33:23 UTC
[dubbo] branch master updated: Fix [3796] fix method parameter bean
generation (#4859)
This is an automated email from the ASF dual-hosted git repository.
iluo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/dubbo.git
The following commit(s) were added to refs/heads/master by this push:
new d7e2ef4 Fix [3796] fix method parameter bean generation (#4859)
d7e2ef4 is described below
commit d7e2ef42b98a80993da7044082c966d4e45f3140
Author: luryson <lu...@qq.com>
AuthorDate: Tue Aug 20 14:33:16 2019 +0800
Fix [3796] fix method parameter bean generation (#4859)
* 封装验证参数实体时,增加同步控制,防止容器启动后第一次调用时的并发问题
封装验证参数实体时,增加同步控制,防止容器启动后第一次调用时的并发问题
* move relevant code to a new method
* add try block to catch NotFoundException when try to generate method-parameter-class
---
.../validation/support/jvalidation/JValidator.java | 58 ++++++++++++++++------
1 file changed, 42 insertions(+), 16 deletions(-)
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 86775de..5d598ea 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);
- }
- 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 ctClass.toClass(clazz.getClassLoader(), null);
+ } else {
+ return Class.forName(parameterClassName, true, clazz.getClassLoader());
}
- return parameterBean;
- } catch (Throwable e) {
- logger.warn(e.getMessage(), e);
- return null;
}
}