enjoy 4.8 release ^_^
This commit is contained in:
@@ -79,7 +79,7 @@ public class Method extends Expr {
|
||||
try {
|
||||
|
||||
MethodInfo methodInfo = MethodKit.getMethod(target.getClass(), methodName, argValues);
|
||||
if (methodInfo != null) {
|
||||
if (methodInfo.notNull()) {
|
||||
return methodInfo.invoke(target, argValues);
|
||||
}
|
||||
|
||||
|
@@ -93,6 +93,29 @@ public class MethodInfo {
|
||||
}
|
||||
return ret.append(")").toString();
|
||||
}
|
||||
|
||||
// --------- 以下代码仅用于支持 NullMethodInfo
|
||||
|
||||
/**
|
||||
* 仅供 NullMethodInfo 继承使用
|
||||
*/
|
||||
protected MethodInfo() {
|
||||
this.key = null;
|
||||
this.clazz = null;
|
||||
this.method = null;
|
||||
this.isVarArgs = false;
|
||||
this.paraTypes = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅仅 NullMethodInfo 会覆盖此方法并返回 false
|
||||
*
|
||||
* 1:MethodKit.getMethod(...) 消除 instanceof 判断
|
||||
* 2:Method.exec(...) 消除 null 值判断
|
||||
*/
|
||||
public boolean notNull() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -41,7 +41,7 @@ public class MethodKit {
|
||||
private static final Set<String> forbiddenMethods = new HashSet<String>(64);
|
||||
private static final Set<Class<?>> forbiddenClasses = new HashSet<Class<?>>(64);
|
||||
private static final Map<Class<?>, Class<?>> primitiveMap = new HashMap<Class<?>, Class<?>>(64);
|
||||
private static final SyncWriteMap<Long, Object> methodCache = new SyncWriteMap<Long, Object>(2048, 0.25F);
|
||||
private static final SyncWriteMap<Long, MethodInfo> methodCache = new SyncWriteMap<Long, MethodInfo>(2048, 0.25F);
|
||||
|
||||
// 初始化在模板中调用 method 时所在的被禁止使用类
|
||||
static {
|
||||
@@ -124,36 +124,17 @@ public class MethodKit {
|
||||
public static MethodInfo getMethod(Class<?> targetClass, String methodName, Object[] argValues) {
|
||||
Class<?>[] argTypes = getArgTypes(argValues);
|
||||
Long key = getMethodKey(targetClass, methodName, argTypes);
|
||||
Object method = methodCache.get(key);
|
||||
MethodInfo method = methodCache.get(key);
|
||||
if (method == null) {
|
||||
// 已确保不会返回 null,对于不存在的 Method,只进行一次获取操作
|
||||
// 提升 null safe 表达式性能,未来需要考虑内存泄漏风险
|
||||
method = doGetMethod(key, targetClass, methodName, argTypes);
|
||||
if (method != null) {
|
||||
methodCache.putIfAbsent(key, method);
|
||||
} else {
|
||||
// 对于不存在的 Method,只进行一次获取操作,主要为了支持 null safe,未来需要考虑内存泄漏风险
|
||||
methodCache.putIfAbsent(key, Void.class);
|
||||
}
|
||||
methodCache.putIfAbsent(key, method);
|
||||
}
|
||||
return method instanceof MethodInfo ? (MethodInfo)method : null;
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 getter 方法
|
||||
* 使用与 Field 相同的 key,避免生成两次 key值
|
||||
* ---> jfinal 3.5 已将此功能转移至 FieldKit
|
||||
public static MethodInfo getGetterMethod(Long key, Class<?> targetClass, String methodName) {
|
||||
Object getterMethod = methodCache.get(key);
|
||||
if (getterMethod == null) {
|
||||
getterMethod = doGetMethod(key, targetClass, methodName, NULL_ARG_TYPES);
|
||||
if (getterMethod != null) {
|
||||
methodCache.putIfAbsent(key, getterMethod);
|
||||
} else {
|
||||
methodCache.putIfAbsent(key, Void.class);
|
||||
}
|
||||
}
|
||||
return getterMethod instanceof MethodInfo ? (MethodInfo)getterMethod : null;
|
||||
} */
|
||||
|
||||
static Class<?>[] getArgTypes(Object[] argValues) {
|
||||
if (argValues == null || argValues.length == 0) {
|
||||
return NULL_ARG_TYPES;
|
||||
@@ -169,7 +150,9 @@ public class MethodKit {
|
||||
if (forbiddenClasses.contains(targetClass)) {
|
||||
throw new RuntimeException("Forbidden class: " + targetClass.getName());
|
||||
}
|
||||
|
||||
// 仅开启 forbiddenClasses 检测
|
||||
// Method、SharedMethod、StaticMethod 已用 MethodKit.isForbiddenMethod(...) 检测
|
||||
// if (forbiddenMethods.contains(methodName)) {
|
||||
// throw new RuntimeException("Forbidden method: " + methodName);
|
||||
// }
|
||||
@@ -186,7 +169,8 @@ public class MethodKit {
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
return NullMethodInfo.me;
|
||||
}
|
||||
|
||||
static boolean matchFixedArgTypes(Class<?>[] paraTypes, Class<?>[] argTypes) {
|
||||
|
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* Copyright (c) 2011-2019, James Zhan 詹波 (jfinal@126.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.jfinal.template.expr.ast;
|
||||
|
||||
/**
|
||||
* NullMethodInfo
|
||||
*
|
||||
* 1:MethodKit.getMethod(...) 消除 instanceof 判断
|
||||
* 2:Method.exec(...) 消除 null 值判断
|
||||
*/
|
||||
public class NullMethodInfo extends MethodInfo {
|
||||
|
||||
public static final NullMethodInfo me = new NullMethodInfo();
|
||||
|
||||
public boolean notNull() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Object invoke(Object target, Object... args) throws ReflectiveOperationException {
|
||||
throw new RuntimeException("The method invoke(Object, Object...) of NullMethodInfo should not be invoked");
|
||||
}
|
||||
}
|
||||
|
@@ -50,6 +50,14 @@ public class StaticMethod extends Expr {
|
||||
} catch (Exception e) {
|
||||
throw new ParseException(e.getMessage(), location, e);
|
||||
}
|
||||
|
||||
if (MethodKit.isForbiddenClass(this.clazz)) {
|
||||
throw new ParseException("Forbidden class: " + this.clazz.getName(), location);
|
||||
}
|
||||
if (MethodKit.isForbiddenMethod(methodName)) {
|
||||
throw new ParseException("Forbidden method: " + methodName, location);
|
||||
}
|
||||
|
||||
this.methodName = methodName;
|
||||
this.exprList = exprList;
|
||||
this.location = location;
|
||||
@@ -61,7 +69,7 @@ public class StaticMethod extends Expr {
|
||||
try {
|
||||
MethodInfo methodInfo = MethodKit.getMethod(clazz, methodName, argValues);
|
||||
|
||||
if (methodInfo != null) {
|
||||
if (methodInfo.notNull()) {
|
||||
if (methodInfo.isStatic()) {
|
||||
return methodInfo.invoke(null, argValues);
|
||||
} else {
|
||||
|
Reference in New Issue
Block a user