package com.baidu.disconf.web.test.common; import java.lang.reflect.Field; import java.lang.reflect.Method; import org.springframework.aop.TargetSource; /** * * @author liaoqiqi * @version 2014-1-26 */ public final class PrivateMethodUtil { private PrivateMethodUtil() { } /** * spring注入对象的私有方法调用 * * @param owner * 注入的对象 * @param methodName * 私有方法名 * @param parameters * 私有方法参数 * @return 私有方法返回值 */ @SuppressWarnings("rawtypes") public static Object invokeMethod(final Object owner, final String methodName, final Object... parameters) throws Exception { Class[] parameterTypes = null; if (parameters != null) { parameterTypes = new Class[parameters.length]; for (int i = 0; i < parameters.length; i++) { parameterTypes[i] = parameters[i].getClass(); } } return invokeMethod(owner, methodName, parameterTypes, parameters); } /** * spring注入对象的私有方法调用 * * @param owner * 注入的对象 * @param methodName * 私有方法名 * @param parameterTypes * 私有方法参数类型 * @param parameters * 私有方法参数 * @return 私有方法返回值 */ @SuppressWarnings({ "rawtypes" }) public static Object invokeMethod(final Object owner, final String methodName, final Class[] parameterTypes, final Object[] parameters) throws Exception { // get class final Class ownerclass = owner.getClass(); // get property try { @SuppressWarnings("unchecked") final Method getTargetClass = ownerclass .getMethod("getTargetSource"); final TargetSource target = (TargetSource) getTargetClass.invoke( owner, new Object[] {}); final Class targetClass = target.getTargetClass(); @SuppressWarnings("unchecked") final Method method = targetClass.getDeclaredMethod(methodName, parameterTypes); if (!method.isAccessible()) { method.setAccessible(true); } final Object targetInstance = target.getTarget(); return method.invoke(targetInstance, parameters); } catch (NoSuchMethodException e) { return invokeMethod(owner, 0, methodName, parameterTypes, parameters); // e.printStackTrace(); } } /** * 普通对象私有方法调用 * * @param owner * : target object * @param classLevel * : 0 means itself, 1 means it's father, and so on... * @param methodName * : name of the target method * @param parameterTypes * : types of the target method's parameters * @param parameters * : parameters of the target method * @return result of invoked method */ @SuppressWarnings("rawtypes") public static Object invokeMethod(final Object owner, final int classLevel, final String methodName, final Class[] parameterTypes, final Object[] parameters) throws Exception { // get class final Class ownerclass = getOwnerclass(owner, classLevel); // get property @SuppressWarnings("unchecked") final Method method = ownerclass.getDeclaredMethod(methodName, parameterTypes); if (!method.isAccessible()) { method.setAccessible(true); } return method.invoke(owner, parameters); } /** * 设置私有成员 * * @param owner * : target object * @param classLevel * : 0 means itself, 1 means it's father, and so on... * @param fieldName * : name of the target field * @param value * : new value of the target field */ @SuppressWarnings("rawtypes") public static void setObjectProperty(final Object owner, final int classLevel, final String fieldName, final Object value) throws Exception { // get class final Class ownerclass = getOwnerclass(owner, classLevel); // get property final Field field = ownerclass.getDeclaredField(fieldName); if (!field.isAccessible()) { field.setAccessible(true); } field.set(owner, value); } /** * 获取私有成员 * * @param owner * : target object * @param classLevel * : 0 means itself, 1 means it's father, and so on... * @param fieldName * : name of the target field * @return value of the target field */ @SuppressWarnings("rawtypes") public static Object getObjectProperty(final Object owner, final int classLevel, final String fieldName) throws Exception { // get class final Class ownerclass = getOwnerclass(owner, classLevel); // get property final Field field = ownerclass.getDeclaredField(fieldName); if (!field.isAccessible()) { field.setAccessible(true); } return field.get(owner); } @SuppressWarnings("rawtypes") private static Class getOwnerclass(final Object owner, final int classLevel) { Class ownerclass = owner.getClass(); for (int i = 0; i < classLevel; i++) { ownerclass = ownerclass.getSuperclass(); } return ownerclass; } }