This commit is contained in:
Looly 2025-01-28 01:34:27 +08:00
parent 190f2c01ad
commit 8efcf8eda7
3 changed files with 48 additions and 19 deletions

View File

@ -166,6 +166,30 @@ public class AnnotationUtil {
return (null == annotationEle) ? null : toCombination(annotationEle).getAnnotation(annotationType); return (null == annotationEle) ? null : toCombination(annotationEle).getAnnotation(annotationType);
} }
/**
* 检查是否包含指定注解<br>
* 注解类传入全名通过{@link Class#forName(String)}加载避免不存在的注解导致的ClassNotFoundException
*
* @param annotationEle {@link AnnotatedElement}可以是ClassMethodFieldConstructorReflectPermission
* @param annotationTypeName 注解类型完整类名
* @return 是否包含指定注解
* @since 6.0.0
*/
@SuppressWarnings({"rawtypes", "unchecked"})
public static boolean hasAnnotation(final AnnotatedElement annotationEle, final String annotationTypeName) {
Class aClass = null;
try {
// issue#IB0JP5Android可能无这个类
aClass = Class.forName(annotationTypeName);
} catch (final ClassNotFoundException e) {
// ignore
}
if(null != aClass){
return hasAnnotation(annotationEle, aClass);
}
return false;
}
/** /**
* 检查是否包含指定注解 * 检查是否包含指定注解
* *

View File

@ -22,7 +22,6 @@ import org.dromara.hutool.core.convert.ConvertUtil;
import org.dromara.hutool.core.reflect.*; import org.dromara.hutool.core.reflect.*;
import org.dromara.hutool.core.reflect.method.MethodInvoker; import org.dromara.hutool.core.reflect.method.MethodInvoker;
import java.beans.Transient;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Type; import java.lang.reflect.Type;
@ -34,6 +33,11 @@ import java.lang.reflect.Type;
*/ */
public class PropDesc { public class PropDesc {
/**
* Transient注解的类名
*/
private static final String TRANSIENT_CLASS_NAME = "java.beans.Transient";
/** /**
* 字段 * 字段
*/ */
@ -73,9 +77,21 @@ public class PropDesc {
* @param setterMethod set方法 * @param setterMethod set方法
*/ */
public PropDesc(final String fieldName, final Method getterMethod, final Method setterMethod) { public PropDesc(final String fieldName, final Method getterMethod, final Method setterMethod) {
this(fieldName, MethodInvoker.of(getterMethod), MethodInvoker.of(setterMethod));
}
/**
* 构造<br>
* Getter和Setter方法设置为默认可访问
*
* @param fieldName 字段名
* @param getter get方法执行器
* @param setter set方法执行器
*/
public PropDesc(final String fieldName, final Invoker getter, final Invoker setter){
this.fieldName = fieldName; this.fieldName = fieldName;
this.getter = null == getterMethod ? null : MethodInvoker.of(getterMethod); this.getter = getter;
this.setter = null == setterMethod ? null : MethodInvoker.of(setterMethod); this.setter = setter;
} }
/** /**
@ -190,7 +206,7 @@ public class PropDesc {
/** /**
* 获取属性值<br> * 获取属性值<br>
* 首先调用字段对应的Getter方法获取值如果Getter方法不存在判断字段如果为public直接获取字段值<br> * 首先调用字段对应的Getter方法获取值如果Getter方法不存在直接获取字段值<br>
* 此方法不检查任何注解使用前需调用 {@link #isReadable(boolean)} 检查是否可读 * 此方法不检查任何注解使用前需调用 {@link #isReadable(boolean)} 检查是否可读
* *
* @param bean Bean对象 * @param bean Bean对象
@ -216,7 +232,7 @@ public class PropDesc {
/** /**
* 获取属性值自动转换属性值类型<br> * 获取属性值自动转换属性值类型<br>
* 首先调用字段对应的Getter方法获取值如果Getter方法不存在判断字段如果为public直接获取字段值 * 首先调用字段对应的Getter方法获取值如果Getter方法不存在直接获取字段值
* *
* @param bean Bean对象 * @param bean Bean对象
* @param targetType 返回属性值需要转换的类型null表示不转换 * @param targetType 返回属性值需要转换的类型null表示不转换
@ -269,7 +285,7 @@ public class PropDesc {
/** /**
* 设置Bean的字段值<br> * 设置Bean的字段值<br>
* 首先调用字段对应的Setter方法如果Setter方法不存在判断字段如果为public直接赋值字段值<br> * 首先调用字段对应的Setter方法如果Setter方法不存在直接赋值字段值<br>
* 此方法不检查任何注解使用前需调用 {@link #isWritable(boolean)} 检查是否可写 * 此方法不检查任何注解使用前需调用 {@link #isWritable(boolean)} 检查是否可写
* *
* @param bean Bean对象 * @param bean Bean对象
@ -432,7 +448,6 @@ public class PropDesc {
* @param getterMethod 读取方法可为{@code null} * @param getterMethod 读取方法可为{@code null}
* @return 是否为Transient关键字修饰的 * @return 是否为Transient关键字修饰的
*/ */
@SuppressWarnings({"rawtypes", "unchecked"})
private static boolean isTransientForGet(final Field field, final Method getterMethod) { private static boolean isTransientForGet(final Field field, final Method getterMethod) {
boolean isTransient = ModifierUtil.hasAny(field, ModifierType.TRANSIENT); boolean isTransient = ModifierUtil.hasAny(field, ModifierType.TRANSIENT);
@ -442,16 +457,7 @@ public class PropDesc {
// 检查注解 // 检查注解
if (!isTransient) { if (!isTransient) {
Class aClass = null; isTransient = AnnotationUtil.hasAnnotation(getterMethod, TRANSIENT_CLASS_NAME);
try {
// issue#IB0JP5Android可能无这个类
aClass = Class.forName("java.beans.Transient");
} catch (final ClassNotFoundException e) {
// ignore
}
if(null != aClass){
isTransient = AnnotationUtil.hasAnnotation(getterMethod, aClass);
}
} }
} }
@ -474,7 +480,7 @@ public class PropDesc {
// 检查注解 // 检查注解
if (!isTransient) { if (!isTransient) {
isTransient = AnnotationUtil.hasAnnotation(setterMethod, Transient.class); isTransient = AnnotationUtil.hasAnnotation(setterMethod, TRANSIENT_CLASS_NAME);
} }
} }

View File

@ -17,7 +17,6 @@
package org.dromara.hutool.core.bean; package org.dromara.hutool.core.bean;
import org.dromara.hutool.core.bean.path.AbstractBeanDesc; import org.dromara.hutool.core.bean.path.AbstractBeanDesc;
import org.dromara.hutool.core.reflect.TypeUtil;
import org.dromara.hutool.core.reflect.method.MethodInvoker; import org.dromara.hutool.core.reflect.method.MethodInvoker;
import org.dromara.hutool.core.reflect.method.MethodNameUtil; import org.dromara.hutool.core.reflect.method.MethodNameUtil;
import org.dromara.hutool.core.reflect.method.MethodUtil; import org.dromara.hutool.core.reflect.method.MethodUtil;