Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
B
basic-api-boot
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-api-boot
Commits
2898075d
提交
2898075d
authored
4月 20, 2022
作者:
谭志磊
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
合并,备份
上级
b7c9acd7
显示空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
0 行增加
和
361 行删除
+0
-361
ReflectUtils.java
...ain/java/com/yiring/common/util/reflect/ReflectUtils.java
+0
-361
没有找到文件。
basic-common/util/src/main/java/com/yiring/common/util/reflect/ReflectUtils.java
deleted
100644 → 0
浏览文件 @
b7c9acd7
/* (C) 2022 YiRing, Inc. */
package
com
.
yiring
.
common
.
util
.
reflect
;
import
com.yiring.common.text.Convert
;
import
com.yiring.common.util.date.DateUtils
;
import
java.lang.reflect.Field
;
import
java.lang.reflect.InvocationTargetException
;
import
java.lang.reflect.Method
;
import
java.lang.reflect.Modifier
;
import
java.lang.reflect.ParameterizedType
;
import
java.lang.reflect.Type
;
import
java.util.Date
;
import
org.apache.commons.lang3.StringUtils
;
import
org.apache.commons.lang3.Validate
;
import
org.apache.poi.ss.usermodel.DateUtil
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
/**
* 反射工具类. 提供调用getter/setter方法, 访问私有变量, 调用私有方法, 获取泛型类型Class, 被AOP过的真实类等工具函数.
*/
@SuppressWarnings
(
"rawtypes"
)
public
class
ReflectUtils
{
private
static
final
String
SETTER_PREFIX
=
"set"
;
private
static
final
String
GETTER_PREFIX
=
"get"
;
private
static
final
String
CGLIB_CLASS_SEPARATOR
=
"$$"
;
private
static
Logger
logger
=
LoggerFactory
.
getLogger
(
ReflectUtils
.
class
);
/**
* 调用Getter方法.
* 支持多级,如:对象名.对象名.方法
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
invokeGetter
(
Object
obj
,
String
propertyName
)
{
Object
object
=
obj
;
for
(
String
name
:
StringUtils
.
split
(
propertyName
,
"."
))
{
String
getterMethodName
=
GETTER_PREFIX
+
StringUtils
.
capitalize
(
name
);
object
=
invokeMethod
(
object
,
getterMethodName
,
new
Class
[]
{},
new
Object
[]
{});
}
return
(
E
)
object
;
}
/**
* 调用Setter方法, 仅匹配方法名。
* 支持多级,如:对象名.对象名.方法
*/
public
static
<
E
>
void
invokeSetter
(
Object
obj
,
String
propertyName
,
E
value
)
{
Object
object
=
obj
;
String
[]
names
=
StringUtils
.
split
(
propertyName
,
"."
);
for
(
int
i
=
0
;
i
<
names
.
length
;
i
++)
{
if
(
i
<
names
.
length
-
1
)
{
String
getterMethodName
=
GETTER_PREFIX
+
StringUtils
.
capitalize
(
names
[
i
]);
object
=
invokeMethod
(
object
,
getterMethodName
,
new
Class
[]
{},
new
Object
[]
{});
}
else
{
String
setterMethodName
=
SETTER_PREFIX
+
StringUtils
.
capitalize
(
names
[
i
]);
invokeMethodByName
(
object
,
setterMethodName
,
new
Object
[]
{
value
});
}
}
}
/**
* 直接读取对象属性值, 无视private/protected修饰符, 不经过getter函数.
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
getFieldValue
(
final
Object
obj
,
final
String
fieldName
)
{
Field
field
=
getAccessibleField
(
obj
,
fieldName
);
if
(
field
==
null
)
{
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
fieldName
+
"] 字段 "
);
return
null
;
}
E
result
=
null
;
try
{
result
=
(
E
)
field
.
get
(
obj
);
}
catch
(
IllegalAccessException
e
)
{
logger
.
error
(
"不可能抛出的异常{}"
,
e
.
getMessage
());
}
return
result
;
}
/**
* 直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数.
*/
public
static
<
E
>
void
setFieldValue
(
final
Object
obj
,
final
String
fieldName
,
final
E
value
)
{
Field
field
=
getAccessibleField
(
obj
,
fieldName
);
if
(
field
==
null
)
{
// throw new IllegalArgumentException("在 [" + obj.getClass() + "] 中,没有找到 [" + fieldName + "] 字段 ");
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
fieldName
+
"] 字段 "
);
return
;
}
try
{
field
.
set
(
obj
,
value
);
}
catch
(
IllegalAccessException
e
)
{
logger
.
error
(
"不可能抛出的异常: {}"
,
e
.
getMessage
());
}
}
/**
* 直接调用对象方法, 无视private/protected修饰符.
* 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用.
* 同时匹配方法名+参数类型,
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
invokeMethod
(
final
Object
obj
,
final
String
methodName
,
final
Class
<?>[]
parameterTypes
,
final
Object
[]
args
)
{
if
(
obj
==
null
||
methodName
==
null
)
{
return
null
;
}
Method
method
=
getAccessibleMethod
(
obj
,
methodName
,
parameterTypes
);
if
(
method
==
null
)
{
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
methodName
+
"] 方法 "
);
return
null
;
}
try
{
return
(
E
)
method
.
invoke
(
obj
,
args
);
}
catch
(
Exception
e
)
{
String
msg
=
"method: "
+
method
+
", obj: "
+
obj
+
", args: "
+
args
+
""
;
throw
convertReflectionExceptionToUnchecked
(
msg
,
e
);
}
}
/**
* 直接调用对象方法, 无视private/protected修饰符,
* 用于一次性调用的情况,否则应使用getAccessibleMethodByName()函数获得Method后反复调用.
* 只匹配函数名,如果有多个同名函数调用第一个。
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
E
>
E
invokeMethodByName
(
final
Object
obj
,
final
String
methodName
,
final
Object
[]
args
)
{
Method
method
=
getAccessibleMethodByName
(
obj
,
methodName
,
args
.
length
);
if
(
method
==
null
)
{
// 如果为空不报错,直接返回空。
logger
.
debug
(
"在 ["
+
obj
.
getClass
()
+
"] 中,没有找到 ["
+
methodName
+
"] 方法 "
);
return
null
;
}
try
{
// 类型转换(将参数数据类型转换为目标方法参数类型)
Class
<?>[]
cs
=
method
.
getParameterTypes
();
for
(
int
i
=
0
;
i
<
cs
.
length
;
i
++)
{
if
(
args
[
i
]
!=
null
&&
!
args
[
i
].
getClass
().
equals
(
cs
[
i
]))
{
if
(
cs
[
i
]
==
String
.
class
)
{
args
[
i
]
=
Convert
.
toStr
(
args
[
i
]);
if
(
StringUtils
.
endsWith
((
String
)
args
[
i
],
".0"
))
{
args
[
i
]
=
StringUtils
.
substringBefore
((
String
)
args
[
i
],
".0"
);
}
}
else
if
(
cs
[
i
]
==
Integer
.
class
)
{
args
[
i
]
=
Convert
.
toInt
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Long
.
class
)
{
args
[
i
]
=
Convert
.
toLong
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Double
.
class
)
{
args
[
i
]
=
Convert
.
toDouble
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Float
.
class
)
{
args
[
i
]
=
Convert
.
toFloat
(
args
[
i
]);
}
else
if
(
cs
[
i
]
==
Date
.
class
)
{
if
(
args
[
i
]
instanceof
String
)
{
args
[
i
]
=
DateUtils
.
parseDate
(
args
[
i
]);
}
else
{
args
[
i
]
=
DateUtil
.
getJavaDate
((
Double
)
args
[
i
]);
}
}
else
if
(
cs
[
i
]
==
boolean
.
class
||
cs
[
i
]
==
Boolean
.
class
)
{
args
[
i
]
=
Convert
.
toBool
(
args
[
i
]);
}
}
}
return
(
E
)
method
.
invoke
(
obj
,
args
);
}
catch
(
Exception
e
)
{
String
msg
=
"method: "
+
method
+
", obj: "
+
obj
+
", args: "
+
args
+
""
;
throw
convertReflectionExceptionToUnchecked
(
msg
,
e
);
}
}
/**
* 循环向上转型, 获取对象的DeclaredField, 并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
*/
public
static
Field
getAccessibleField
(
final
Object
obj
,
final
String
fieldName
)
{
// 为空不报错。直接返回 null
if
(
obj
==
null
)
{
return
null
;
}
Validate
.
notBlank
(
fieldName
,
"fieldName can't be blank"
);
for
(
Class
<?>
superClass
=
obj
.
getClass
();
superClass
!=
Object
.
class
;
superClass
=
superClass
.
getSuperclass
()
)
{
try
{
Field
field
=
superClass
.
getDeclaredField
(
fieldName
);
makeAccessible
(
field
);
return
field
;
}
catch
(
NoSuchFieldException
e
)
{
continue
;
}
}
return
null
;
}
/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 匹配函数名+参数类型。
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
*/
public
static
Method
getAccessibleMethod
(
final
Object
obj
,
final
String
methodName
,
final
Class
<?>...
parameterTypes
)
{
// 为空不报错。直接返回 null
if
(
obj
==
null
)
{
return
null
;
}
Validate
.
notBlank
(
methodName
,
"methodName can't be blank"
);
for
(
Class
<?>
searchType
=
obj
.
getClass
();
searchType
!=
Object
.
class
;
searchType
=
searchType
.
getSuperclass
()
)
{
try
{
Method
method
=
searchType
.
getDeclaredMethod
(
methodName
,
parameterTypes
);
makeAccessible
(
method
);
return
method
;
}
catch
(
NoSuchMethodException
e
)
{
continue
;
}
}
return
null
;
}
/**
* 循环向上转型, 获取对象的DeclaredMethod,并强制设置为可访问.
* 如向上转型到Object仍无法找到, 返回null.
* 只匹配函数名。
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
*/
public
static
Method
getAccessibleMethodByName
(
final
Object
obj
,
final
String
methodName
,
int
argsNum
)
{
// 为空不报错。直接返回 null
if
(
obj
==
null
)
{
return
null
;
}
Validate
.
notBlank
(
methodName
,
"methodName can't be blank"
);
for
(
Class
<?>
searchType
=
obj
.
getClass
();
searchType
!=
Object
.
class
;
searchType
=
searchType
.
getSuperclass
()
)
{
Method
[]
methods
=
searchType
.
getDeclaredMethods
();
for
(
Method
method
:
methods
)
{
if
(
method
.
getName
().
equals
(
methodName
)
&&
method
.
getParameterTypes
().
length
==
argsNum
)
{
makeAccessible
(
method
);
return
method
;
}
}
}
return
null
;
}
/**
* 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
*/
public
static
void
makeAccessible
(
Method
method
)
{
if
(
(
!
Modifier
.
isPublic
(
method
.
getModifiers
())
||
!
Modifier
.
isPublic
(
method
.
getDeclaringClass
().
getModifiers
())
)
&&
!
method
.
isAccessible
()
)
{
method
.
setAccessible
(
true
);
}
}
/**
* 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。
*/
public
static
void
makeAccessible
(
Field
field
)
{
if
(
(
!
Modifier
.
isPublic
(
field
.
getModifiers
())
||
!
Modifier
.
isPublic
(
field
.
getDeclaringClass
().
getModifiers
())
||
Modifier
.
isFinal
(
field
.
getModifiers
())
)
&&
!
field
.
isAccessible
()
)
{
field
.
setAccessible
(
true
);
}
}
/**
* 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处
* 如无法找到, 返回Object.class.
*/
@SuppressWarnings
(
"unchecked"
)
public
static
<
T
>
Class
<
T
>
getClassGenricType
(
final
Class
clazz
)
{
return
getClassGenricType
(
clazz
,
0
);
}
/**
* 通过反射, 获得Class定义中声明的父类的泛型参数的类型.
* 如无法找到, 返回Object.class.
*/
public
static
Class
getClassGenricType
(
final
Class
clazz
,
final
int
index
)
{
Type
genType
=
clazz
.
getGenericSuperclass
();
if
(!(
genType
instanceof
ParameterizedType
))
{
logger
.
debug
(
clazz
.
getSimpleName
()
+
"'s superclass not ParameterizedType"
);
return
Object
.
class
;
}
Type
[]
params
=
((
ParameterizedType
)
genType
).
getActualTypeArguments
();
if
(
index
>=
params
.
length
||
index
<
0
)
{
logger
.
debug
(
"Index: "
+
index
+
", Size of "
+
clazz
.
getSimpleName
()
+
"'s Parameterized Type: "
+
params
.
length
);
return
Object
.
class
;
}
if
(!(
params
[
index
]
instanceof
Class
))
{
logger
.
debug
(
clazz
.
getSimpleName
()
+
" not set the actual class on superclass generic parameter"
);
return
Object
.
class
;
}
return
(
Class
)
params
[
index
];
}
public
static
Class
<?>
getUserClass
(
Object
instance
)
{
if
(
instance
==
null
)
{
throw
new
RuntimeException
(
"Instance must not be null"
);
}
Class
clazz
=
instance
.
getClass
();
if
(
clazz
!=
null
&&
clazz
.
getName
().
contains
(
CGLIB_CLASS_SEPARATOR
))
{
Class
<?>
superClass
=
clazz
.
getSuperclass
();
if
(
superClass
!=
null
&&
!
Object
.
class
.
equals
(
superClass
))
{
return
superClass
;
}
}
return
clazz
;
}
/**
* 将反射时的checked exception转换为unchecked exception.
*/
public
static
RuntimeException
convertReflectionExceptionToUnchecked
(
String
msg
,
Exception
e
)
{
if
(
e
instanceof
IllegalAccessException
||
e
instanceof
IllegalArgumentException
||
e
instanceof
NoSuchMethodException
)
{
return
new
IllegalArgumentException
(
msg
,
e
);
}
else
if
(
e
instanceof
InvocationTargetException
)
{
return
new
RuntimeException
(
msg
,
((
InvocationTargetException
)
e
).
getTargetException
());
}
return
new
RuntimeException
(
msg
,
e
);
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论