All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.novelweb.tool.upload.fastdfs.utils.ReflectionsUtils Maven / Gradle / Ivy

package cn.novelweb.tool.upload.fastdfs.utils;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;

import java.lang.reflect.*;

/**
 * 反射工具类(自己实现的)
* 1.提供调用getter/setter方法
* 2.访问私有变量
* 3.调用私有方法
* 4.获取泛型类型Class
* 5.被AOP过的真实类等工具函数
*

016-4-29 23:56

* * @author LiZW **/ @Slf4j public class ReflectionsUtils { /** * set方法前缀 */ private static final String SETTER_PREFIX = "set"; /** * get方法前缀 */ private static final String GETTER_PREFIX = "get"; private static final String CGLIB_CLASS_SEPARATOR = "$$"; /** * 将checked exception转换为unchecked exception * * @param e checked exception * @return 返回RuntimeException */ private static RuntimeException convertReflectionExceptionToUnchecked(Throwable e) { if (e instanceof IllegalAccessException || e instanceof IllegalArgumentException || e instanceof NoSuchMethodException) { return new IllegalArgumentException(e); } else if (e instanceof InvocationTargetException) { return new RuntimeException(((InvocationTargetException) e).getTargetException()); } else if (e instanceof RuntimeException) { return (RuntimeException) e; } return new RuntimeException(e); } /** * 改变private/protected的方法为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 * * @param method 目标方法实例 */ private static void makeAccessible(Method method) { boolean isTrue = (!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic( method.getDeclaringClass().getModifiers())) && !method.isAccessible(); if (isTrue) { method.setAccessible(true); } } /** * 改变private/protected的成员变量为public,尽量不调用实际改动的语句,避免JDK的SecurityManager抱怨。 * * @param field 成员变量实例 */ private static void makeAccessible(Field field) { boolean isTrue = (!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier.isFinal(field.getModifiers())) && !field.isAccessible(); if (isTrue) { field.setAccessible(true); } } /** * 在给定的对象中查找指定的方法,获取不到就在其父类中找(循环向上转型),获取到方法之后强行设置成public返回
* 如向上转型到Object仍无法找到, 返回null
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
* * @param obj 目标对象 * @param methodName 方法名称 * @param parameterTypes 方法签名参数类型 * @return 方法实例,获取失败返回null */ private static Method getAccessibleMethod(final Object obj, final String methodName, final Class... parameterTypes) { Class searchType = obj.getClass(); while (searchType != Object.class) { try { Method method = searchType.getDeclaredMethod(methodName, parameterTypes); if (method != null) { // 强制设置方法可以访问(public) makeAccessible(method); return method; } else { continue; } } catch (Throwable e) { log.error("getAccessibleMethod-反射错误,找不到方法", e); // Method不在当前类定义,继续向上转型 } // 获取父类类型,继续查找方法 searchType = searchType.getSuperclass(); } return null; } /** * 在给定的对象中查找指定的方法,获取不到就在其父类中找(循环向上转型),获取到方法之后强行设置成public返回
* 如向上转型到Object仍无法找到, 返回null
* 用于方法需要被多次调用的情况. 先使用本函数先取得Method,然后调用Method.invoke(Object obj, Object... args)
* * @param obj 目标对象 * @param methodName 方法名称 * @return 方法实例,获取失败返回null */ private static Method getAccessibleMethodByName(final Object obj, final String methodName) { Class searchType = obj.getClass(); while (searchType != Object.class) { Method[] methods = searchType.getDeclaredMethods(); for (Method method : methods) { if (method.getName().equals(methodName)) { // 强制设置方法可以访问(public) makeAccessible(method); return method; } } // 获取父类类型,继续查找方法 searchType = searchType.getSuperclass(); } return null; } /** * 在给定的对象中查找指定的成员变量,获取不到就在其父类中找(循环向上转型),获取到之后强行设置成public返回
* * @param obj 目标对象 * @param fieldName 成员变量名称 * @return 成员变量实例 */ private static Field getAccessibleField(final Object obj, final String fieldName) { Class superClass = obj.getClass(); while (superClass != Object.class) { try { Field field = superClass.getDeclaredField(fieldName); if (field != null) { // 强制设置成员变量可以访问(public) makeAccessible(field); return field; } else { continue; } } catch (Throwable e) { log.error("getAccessibleField-反射错误,找不到字段", e); // Field不在当前类定义,继续向上转型 } // 获取父类类型,继续查找字段 superClass = superClass.getSuperclass(); } return null; } /** * 直接调用对象方法, 无视private/protected修饰符
* 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用
* * @param obj 目标对象 * @param methodName 方法名称 * @param parameterTypes 方法签名参数类型 * @param args 调用方法参数值 * @return 返回方法调用返回结果 */ private static Object invokeMethod(final Object obj, final String methodName, final Class[] parameterTypes, final Object[] args) { Method method = getAccessibleMethod(obj, methodName, parameterTypes); if (method == null) { throw new IllegalArgumentException("invokeMethod-在对象[" + obj + "]中找不到方法 [" + methodName + "]"); } try { return method.invoke(obj, args); } catch (Exception e) { log.error("invokeMethod-反射调用方法失败", e); throw convertReflectionExceptionToUnchecked(e); } } /** * 直接调用对象方法, 无视private/protected修饰符
* 用于一次性调用的情况,否则应使用getAccessibleMethod()函数获得Method后反复调用
* 只匹配方法名,如果有多个相同的方法名,则只调用第一个
* * @param obj 目标对象 * @param methodName 方法名称 * @param args 方法签名参数类型 * @return 返回方法调用返回结果 */ private static Object invokeMethodByName(final Object obj, final String methodName, final Object[] args) { Method method = getAccessibleMethodByName(obj, methodName); if (method == null) { throw new IllegalArgumentException("invokeMethod-在对象[" + obj + "]中找不到方法 [" + methodName + "]"); } try { return method.invoke(obj, args); } catch (Exception e) { log.error("invokeMethodByName-反射调用方法失败", e); throw convertReflectionExceptionToUnchecked(e); } } /** * 反射调用调用Getter方法 * * @param obj 目标对象 * @param propertyName 属性名,支持多级,如:对象名.对象名.方法 * @return 调用结果 */ public static Object invokeGetter(Object obj, String propertyName) { Object object = obj; String[] propertyArray = StringUtils.split(propertyName, "."); for (String name : propertyArray) { String getterMethodName = GETTER_PREFIX + StringUtils.capitalize(name); object = invokeMethod(object, getterMethodName, new Class[]{}, new Object[]{}); } return object; } /** * 反射调用Setter方法 * * @param obj 目标对象 * @param propertyName 属性名,支持多级,如:对象名.对象名.方法 * @param value 参数值 */ public static void invokeSetter(Object obj, String propertyName, Object 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函数 * * @param obj 目标对象 * @param fieldName 属性名,不支持:属性名.属性名.属性名... * @return 属性值 */ public static Object getFieldValue(final Object obj, final String fieldName) { Field field = getAccessibleField(obj, fieldName); if (field == null) { throw new IllegalArgumentException("getFieldValue-在对象[" + obj + "]中找不到字段[" + fieldName + "]"); } Object result; try { result = field.get(obj); } catch (Throwable e) { log.error("getFieldValue-通过反射直接读取对象属性值失败", e); throw convertReflectionExceptionToUnchecked(e); } return result; } /** * 通过反射直接设置对象属性值, 无视private/protected修饰符, 不经过setter函数 * * @param obj 目标对象 * @param fieldName 属性名,不支持:属性名.属性名.属性名... * @param value 属性值 */ public static void setFieldValue(final Object obj, final String fieldName, final Object value) { Field field = getAccessibleField(obj, fieldName); if (field == null) { throw new IllegalArgumentException("getFieldValue-在对象[" + obj + "]中找不到字段[" + fieldName + "]"); } try { field.set(obj, value); } catch (Throwable e) { log.error("getFieldValue-通过反射直接设置对象属性值", e); throw convertReflectionExceptionToUnchecked(e); } } /** * 通过反射, 获得Class定义中声明的父类的泛型参数的类型
* 如无法找到, 返回Object.class
* 如:public UserDao extends HibernateDao<User> * * @param clazz 目标Class * @param index 泛型类型所处的位置,例如:直接父类的泛型使用0 * @return the 返回父类层级中的泛型类型,如无法找到, 返回Object.class */ private static Class getClassGenricType(final Class clazz, final int index) { Type genType = clazz.getGenericSuperclass(); if (!(genType instanceof ParameterizedType)) { log.warn(clazz.getSimpleName() + "类不是ParameterizedType的子类"); return Object.class; } Type[] params = ((ParameterizedType) genType).getActualTypeArguments(); if (index >= params.length || index < 0) { log.warn("Index: " + index + ", Size of " + clazz.getSimpleName() + "'s Parameterized Type: " + params.length); return Object.class; } if (!(params[index] instanceof Class)) { if (params[index] instanceof ParameterizedType) { Type type = ((ParameterizedType) params[index]).getRawType(); if (type instanceof Class) { return (Class) type; } } Log.debug(clazz.getSimpleName() + "没有设置超泛型参数的实际类"); return Object.class; } return (Class) params[index]; } /** * 通过反射, 获得Class定义中声明的泛型参数的类型, 注意泛型必须定义在父类处
* 如无法找到, 返回Object.class
* 如:public UserDao extends HibernateDao<User> * * @param clazz 目标Class * @return 返回父类中的泛型类型,如无法找到, 返回Object.class */ @SuppressWarnings("unchecked") public static Class getClassGenricType(final Class clazz) { return getClassGenricType(clazz, 0); } /** * 获取实际使用的类,获取被AOP过的真实类 * * @param instance 目标对象 * @return 返回实际使用的类 */ public static Class getUserClass(Object instance) { 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; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy