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 {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue