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
This commit is contained in:
parent
06f719086e
commit
d7e2ef42b9
|
|
@ -119,8 +119,41 @@ public class JValidator implements Validator {
|
||||||
try {
|
try {
|
||||||
parameterClass = Class.forName(parameterClassName, true, clazz.getClassLoader());
|
parameterClass = Class.forName(parameterClassName, true, clazz.getClassLoader());
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
ClassPool pool = ClassGenerator.getClassPool(clazz.getClassLoader());
|
parameterClass = generateMethodParameterClass(clazz, method, parameterClassName);
|
||||||
CtClass ctClass = pool.makeClass(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 classFile = ctClass.getClassFile();
|
||||||
classFile.setVersionToJava5();
|
classFile.setVersionToJava5();
|
||||||
ctClass.addConstructor(CtNewConstructor.defaultConstructor(pool.getCtClass(parameterClassName)));
|
ctClass.addConstructor(CtNewConstructor.defaultConstructor(pool.getCtClass(parameterClassName)));
|
||||||
|
|
@ -134,16 +167,16 @@ public class JValidator implements Validator {
|
||||||
for (Annotation annotation : annotations) {
|
for (Annotation annotation : annotations) {
|
||||||
if (annotation.annotationType().isAnnotationPresent(Constraint.class)) {
|
if (annotation.annotationType().isAnnotationPresent(Constraint.class)) {
|
||||||
javassist.bytecode.annotation.Annotation ja = new javassist.bytecode.annotation.Annotation(
|
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();
|
Method[] members = annotation.annotationType().getMethods();
|
||||||
for (Method member : members) {
|
for (Method member : members) {
|
||||||
if (Modifier.isPublic(member.getModifiers())
|
if (Modifier.isPublic(member.getModifiers())
|
||||||
&& member.getParameterTypes().length == 0
|
&& member.getParameterTypes().length == 0
|
||||||
&& member.getDeclaringClass() == annotation.annotationType()) {
|
&& member.getDeclaringClass() == annotation.annotationType()) {
|
||||||
Object value = member.invoke(annotation);
|
Object value = member.invoke(annotation);
|
||||||
if (null != value) {
|
if (null != value) {
|
||||||
MemberValue memberValue = createMemberValue(
|
MemberValue memberValue = createMemberValue(
|
||||||
classFile.getConstPool(), pool.get(member.getReturnType().getName()), value);
|
classFile.getConstPool(), pool.get(member.getReturnType().getName()), value);
|
||||||
ja.addMemberValue(member.getName(), memberValue);
|
ja.addMemberValue(member.getName(), memberValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -156,17 +189,10 @@ public class JValidator implements Validator {
|
||||||
ctField.getFieldInfo().addAttribute(attribute);
|
ctField.getFieldInfo().addAttribute(attribute);
|
||||||
ctClass.addField(ctField);
|
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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue