Browse Source

enhance aop

Looly 6 years ago
parent
commit
45609bc22b

+ 13 - 13
hutool-aop/src/main/java/cn/hutool/aop/aspects/Aspect.java

@@ -4,19 +4,19 @@ import java.lang.reflect.Method;
 
 /**
  * 切面接口
- * 
+ *
  * @author looly
  * @author ted.L
  * @since 4.18
  */
-public interface Aspect{
+public interface Aspect {
 
 	/**
 	 * 目标方法执行前的操作
-	 * 
+	 *
 	 * @param target 目标对象
 	 * @param method 目标方法
-	 * @param args 参数
+	 * @param args   参数
 	 * @return 是否继续执行接下来的操作
 	 */
 	boolean before(Object target, Method method, Object[] args);
@@ -24,25 +24,25 @@ public interface Aspect{
 	/**
 	 * 目标方法执行后的操作
 	 * 如果 target.method 抛出异常且
-	 * @see Aspect#afterException 返回true,则不会执行此操作
-	 * 如果
-	 * @see Aspect#afterException 返回false,则无论target.method是否抛出异常,均会执行此操作
 	 *
-	 * @param target 目标对象
-	 * @param method 目标方法
-	 * @param args 参数
+	 * @param target    目标对象
+	 * @param method    目标方法
+	 * @param args      参数
 	 * @param returnVal 目标方法执行返回值
 	 * @return 是否允许返回值(接下来的操作)
+	 * @see Aspect#afterException 返回true,则不会执行此操作
+	 * 如果
+	 * @see Aspect#afterException 返回false,则无论target.method是否抛出异常,均会执行此操作
 	 */
 	boolean after(Object target, Method method, Object[] args, Object returnVal);
 
 	/**
 	 * 目标方法抛出异常时的操作
-	 * 
+	 *
 	 * @param target 目标对象
 	 * @param method 目标方法
-	 * @param args 参数
-	 * @param e 异常
+	 * @param args   参数
+	 * @param e      异常
 	 * @return 是否允许抛出异常
 	 */
 	boolean afterException(Object target, Method method, Object[] args, Throwable e);

+ 20 - 16
hutool-aop/src/main/java/cn/hutool/aop/aspects/SimpleAspect.java

@@ -6,38 +6,42 @@ import java.lang.reflect.Method;
 /**
  * 简单切面类,不做任何操作<br>
  * 可以继承此类实现自己需要的方法即可
- * 
- * @author Looly
- * @author ted.L
  *
+ * @author Looly, ted.L
  */
-public abstract class SimpleAspect implements Aspect, Serializable{
+public class SimpleAspect implements Aspect, Serializable {
 	private static final long serialVersionUID = 1L;
 
-    /**
-     * @see Aspect#before(Object, Method, Object[])
-     * @return 是否继续执行接下来的操作 默认值true
-     */
 	@Override
 	public boolean before(Object target, Method method, Object[] args) {
 		//继承此类后实现此方法
 		return true;
 	}
 
-    /**
-     * @see Aspect#after(Object, Method, Object[], Object)
-     * @return 是否允许返回值(接下来的操作) 默认值true
-     */
+
+	/**
+	 * 目标方法执行后的操作
+	 * 如果 target.method 抛出异常且
+	 *
+	 * @param target 目标对象
+	 * @param method 目标方法
+	 * @param args   参数
+	 * @return 是否允许返回值(接下来的操作)
+	 * @see Aspect#afterException 返回true,则不会执行此操作
+	 * 如果
+	 * @see Aspect#afterException 返回false,则无论target.method是否抛出异常,均会执行此操作
+	 */
+	public boolean after(Object target, Method method, Object[] args) {
+		//继承此类后实现此方法
+		return after(target, method, args, null);
+	}
+
 	@Override
 	public boolean after(Object target, Method method, Object[] args, Object returnVal) {
 		//继承此类后实现此方法
 		return true;
 	}
 
-    /**
-     * @see Aspect#afterException(Object, Method, Object[], Throwable)
-     * @return 是否允许抛出异常 默认值true
-     */
 	@Override
 	public boolean afterException(Object target, Method method, Object[] args, Throwable e) {
 		//继承此类后实现此方法

+ 17 - 13
hutool-aop/src/main/java/cn/hutool/aop/aspects/TimeIntervalAspect.java

@@ -8,23 +8,27 @@ import cn.hutool.core.util.StrUtil;
 
 /**
  * 通过日志打印方法的执行时间的切面
- * @author Looly
  *
+ * @author Looly
  */
 public class TimeIntervalAspect extends SimpleAspect {
-    private static final long serialVersionUID = 1L;
+	private static final long serialVersionUID = 1L;
 
-    private TimeInterval      interval         = new TimeInterval();
+	private TimeInterval interval = new TimeInterval();
 
-    @Override
-    public boolean before(Object target, Method method, Object[] args) {
-        interval.start();
-        return true;
-    }
+	@Override
+	public boolean before(Object target, Method method, Object[] args) {
+		interval.start();
+		return true;
+	}
 
-    @Override
-    public boolean after(Object target, Method method, Object[] args, Object returnVal) {
-        Console.log("Method [{}.{}] execute spend [{}]ms return value [{}]", target.getClass().getName(), method.getName(), interval.intervalMs(), StrUtil.toString(returnVal));
-        return true;
-    }
+	@Override
+	public boolean after(Object target, Method method, Object[] args, Object returnVal) {
+		Console.log("Method [{}.{}] execute spend [{}]ms return value [{}]",
+				target.getClass().getName(), //
+				method.getName(), //
+				interval.intervalMs(), //
+				returnVal);
+		return true;
+	}
 }

+ 14 - 19
hutool-aop/src/main/java/cn/hutool/aop/interceptor/CglibInterceptor.java

@@ -1,30 +1,27 @@
 package cn.hutool.aop.interceptor;
 
-import java.io.Serializable;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
 import cn.hutool.aop.aspects.Aspect;
-import cn.hutool.core.exceptions.UtilException;
 import net.sf.cglib.proxy.MethodInterceptor;
 import net.sf.cglib.proxy.MethodProxy;
 
+import java.io.Serializable;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
 /**
  * Cglib实现的动态代理切面
- * 
- * @author looly
- * @author ted.L
  *
+ * @author looly, ted.L
  */
 public class CglibInterceptor implements MethodInterceptor, Serializable {
 	private static final long serialVersionUID = 1L;
-	
+
 	private Object target;
 	private Aspect aspect;
 
 	/**
 	 * 构造
-	 * 
+	 *
 	 * @param target 被代理对象
 	 * @param aspect 切面实现
 	 */
@@ -40,22 +37,20 @@ public class CglibInterceptor implements MethodInterceptor, Serializable {
 	@Override
 	public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
 		Object result = null;
+
+		// 开始前回调
 		if (aspect.before(target, method, args)) {
 			try {
-				// result = ReflectUtil.invoke(target, method, args);
 				result = proxy.invokeSuper(obj, args);
-			} catch (UtilException e) {
-				final Throwable cause = e.getCause();
-				if (!(e.getCause() instanceof InvocationTargetException)) {
-					// 其它异常属于代理的异常,直接抛出
+			} catch (InvocationTargetException e) {
+				// 异常回调(只捕获业务代码导致的异常,而非反射导致的异常)
+				if (aspect.afterException(target, method, args, e.getTargetException())) {
 					throw e;
 				}
-				if(aspect.afterException(target, method, args, ((InvocationTargetException) cause).getTargetException())){
-					throw e;
-				}
-
 			}
 		}
+
+		// 结束执行回调
 		if (aspect.after(target, method, args, result)) {
 			return result;
 		}

+ 14 - 12
hutool-aop/src/main/java/cn/hutool/aop/interceptor/JdkInterceptor.java

@@ -7,16 +7,16 @@ import java.lang.reflect.Method;
 
 import cn.hutool.aop.aspects.Aspect;
 import cn.hutool.core.exceptions.UtilException;
+import cn.hutool.core.util.ClassUtil;
 import cn.hutool.core.util.ReflectUtil;
 
 /**
  * JDK实现的动态代理切面
- * 
+ *
  * @author Looly
  * @author ted.L
- *
  */
-public class JdkInterceptor implements InvocationHandler, Serializable{
+public class JdkInterceptor implements InvocationHandler, Serializable {
 	private static final long serialVersionUID = 1L;
 
 	private Object target;
@@ -24,7 +24,7 @@ public class JdkInterceptor implements InvocationHandler, Serializable{
 
 	/**
 	 * 构造
-	 * 
+	 *
 	 * @param target 被代理对象
 	 * @param aspect 切面实现
 	 */
@@ -42,20 +42,22 @@ public class JdkInterceptor implements InvocationHandler, Serializable{
 		final Object target = this.target;
 		final Aspect aspect = this.aspect;
 		Object result = null;
+
+		// 开始前回调
 		if (aspect.before(target, method, args)) {
+			ReflectUtil.setAccessible(method);
+
 			try {
-				result = ReflectUtil.invoke(target, method, args);
-			} catch (UtilException e) {
-				final Throwable cause = e.getCause();
-				if (!(e.getCause() instanceof InvocationTargetException)) {
-					// 其它异常属于代理的异常,直接抛出
-					throw e;
-				}
-				if(aspect.afterException(target, method, args, ((InvocationTargetException) cause).getTargetException())){
+				result = method.invoke(ClassUtil.isStatic(method) ? null : target, args);
+			} catch (InvocationTargetException e) {
+				// 异常回调(只捕获业务代码导致的异常,而非反射导致的异常)
+				if (aspect.afterException(target, method, args, e.getTargetException())) {
 					throw e;
 				}
 			}
 		}
+
+		// 结束执行回调
 		if (aspect.after(target, method, args, result)) {
 			return result;
 		}

+ 6 - 4
hutool-aop/src/main/java/cn/hutool/aop/proxy/JdkProxyFactory.java

@@ -6,16 +6,18 @@ import cn.hutool.aop.interceptor.JdkInterceptor;
 
 /**
  * JDK实现的切面代理
- * 
- * @author looly
  *
+ * @author looly
  */
-public class JdkProxyFactory extends ProxyFactory{
+public class JdkProxyFactory extends ProxyFactory {
 	private static final long serialVersionUID = 1L;
 
 	@Override
 	@SuppressWarnings("unchecked")
 	public <T> T proxy(T target, Aspect aspect) {
-		return (T) ProxyUtil.newProxyInstance(target.getClass().getClassLoader(), new JdkInterceptor(target, aspect), target.getClass().getInterfaces());
+		return (T) ProxyUtil.newProxyInstance(//
+				target.getClass().getClassLoader(), //
+				new JdkInterceptor(target, aspect), //
+				target.getClass().getInterfaces());
 	}
 }

+ 47 - 49
hutool-aop/src/test/java/cn/hutool/aop/test/AopTest.java

@@ -1,5 +1,6 @@
 package cn.hutool.aop.test;
 
+import cn.hutool.core.lang.Console;
 import org.junit.Assert;
 import org.junit.Test;
 
@@ -8,66 +9,63 @@ import cn.hutool.aop.aspects.TimeIntervalAspect;
 
 /**
  * AOP模块单元测试
- * 
- * @author Looly
  *
+ * @author Looly
  */
 public class AopTest {
 
-    @Test
-    public void aopTest() {
-        Animal cat = ProxyUtil.proxy(new Cat(), TimeIntervalAspect.class);
-        String result = cat.eat();
-        Assert.assertEquals("猫吃鱼", result);
-        cat.seize();
-    }
+	@Test
+	public void aopTest() {
+		Animal cat = ProxyUtil.proxy(new Cat(), TimeIntervalAspect.class);
+		String result = cat.eat();
+		Assert.assertEquals("猫吃鱼", result);
+		cat.seize();
+	}
 
-    @Test
-    public void aopByCglibTest() {
-        Dog dog = ProxyUtil.proxy(new Dog(), TimeIntervalAspect.class);
-        String result = dog.eat();
-        Assert.assertEquals("狗吃肉", result);
+	@Test
+	public void aopByCglibTest() {
+		Dog dog = ProxyUtil.proxy(new Dog(), TimeIntervalAspect.class);
+		String result = dog.eat();
+		Assert.assertEquals("狗吃肉", result);
 		dog.seize();
-    }
+	}
 
-    interface Animal {
-        String eat();
+	interface Animal {
+		String eat();
 
-        void seize();
-    }
+		void seize();
+	}
 
-    /**
-     * 有接口
-     * 
-     * @author looly
-     *
-     */
-    static class Cat implements Animal {
+	/**
+	 * 有接口
+	 *
+	 * @author looly
+	 */
+	static class Cat implements Animal {
 
-        @Override
-        public String eat() {
-            return "猫吃鱼";
-        }
+		@Override
+		public String eat() {
+			return "猫吃鱼";
+		}
 
-        @Override
-        public void seize() {
-            System.out.println("抓了条鱼");
-        }
-    }
+		@Override
+		public void seize() {
+			Console.log("抓了条鱼");
+		}
+	}
 
-    /**
-     * 无接口
-     * 
-     * @author looly
-     *
-     */
-    static class Dog {
-        public String eat() {
-            return "狗吃肉";
-        }
+	/**
+	 * 无接口
+	 *
+	 * @author looly
+	 */
+	static class Dog {
+		public String eat() {
+			return "狗吃肉";
+		}
 
-        public void seize() {
-            System.out.println("抓了只鸡");
-        }
-    }
+		public void seize() {
+            Console.log("抓了只鸡");
+		}
+	}
 }

+ 148 - 123
hutool-core/src/main/java/cn/hutool/core/util/ReflectUtil.java

@@ -1,5 +1,13 @@
 package cn.hutool.core.util;
 
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.exceptions.UtilException;
+import cn.hutool.core.lang.Assert;
+import cn.hutool.core.lang.Filter;
+import cn.hutool.core.lang.SimpleCache;
+
+import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -8,34 +16,34 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
-import cn.hutool.core.collection.CollectionUtil;
-import cn.hutool.core.convert.Convert;
-import cn.hutool.core.exceptions.UtilException;
-import cn.hutool.core.lang.Assert;
-import cn.hutool.core.lang.Filter;
-import cn.hutool.core.lang.SimpleCache;
-
 /**
  * 反射工具类
- * 
+ *
  * @author Looly
  * @since 3.0.9
  */
 public class ReflectUtil {
 
-	/** 构造对象缓存 */
+	/**
+	 * 构造对象缓存
+	 */
 	private static final SimpleCache<Class<?>, Constructor<?>[]> CONSTRUCTORS_CACHE = new SimpleCache<>();
-	/** 字段缓存 */
+	/**
+	 * 字段缓存
+	 */
 	private static final SimpleCache<Class<?>, Field[]> FIELDS_CACHE = new SimpleCache<>();
-	/** 方法缓存 */
+	/**
+	 * 方法缓存
+	 */
 	private static final SimpleCache<Class<?>, Method[]> METHODS_CACHE = new SimpleCache<>();
 
 	// --------------------------------------------------------------------------------------------------------- Constructor
+
 	/**
 	 * 查找类中的指定参数的构造方法,如果找到构造方法,会自动设置可访问为true
-	 * 
-	 * @param <T> 对象类型
-	 * @param clazz 类
+	 *
+	 * @param <T>            对象类型
+	 * @param clazz          
 	 * @param parameterTypes 参数类型,只要任何一个参数是指定参数的父类或接口或相等即可,此参数可以不传
 	 * @return 构造方法,如果未找到返回null
 	 */
@@ -51,7 +59,7 @@ public class ReflectUtil {
 			pts = constructor.getParameterTypes();
 			if (ClassUtil.isAllAssignableFrom(pts, parameterTypes)) {
 				// 构造可访问
-				constructor.setAccessible(true);
+				setAccessible(constructor);
 				return (Constructor<T>) constructor;
 			}
 		}
@@ -60,8 +68,8 @@ public class ReflectUtil {
 
 	/**
 	 * 获得一个类中所有构造列表
-	 * 
-	 * @param <T> 构造的对象类型
+	 *
+	 * @param <T>       构造的对象类型
 	 * @param beanClass 类
 	 * @return 字段列表
 	 * @throws SecurityException 安全检查异常
@@ -80,7 +88,7 @@ public class ReflectUtil {
 
 	/**
 	 * 获得一个类中所有字段列表,直接反射获取,无缓存
-	 * 
+	 *
 	 * @param beanClass 类
 	 * @return 字段列表
 	 * @throws SecurityException 安全检查异常
@@ -91,11 +99,12 @@ public class ReflectUtil {
 	}
 
 	// --------------------------------------------------------------------------------------------------------- Field
+
 	/**
 	 * 查找指定类中是否包含指定名称对应的字段,包括所有字段(包括非public字段),也包括父类和Object类的字段
-	 * 
+	 *
 	 * @param beanClass 被查找字段的类,不能为null
-	 * @param name 字段名
+	 * @param name      字段名
 	 * @return 是否包含字段
 	 * @throws SecurityException 安全异常
 	 * @since 4.1.21
@@ -103,12 +112,12 @@ public class ReflectUtil {
 	public static boolean hasField(Class<?> beanClass, String name) throws SecurityException {
 		return null != getField(beanClass, name);
 	}
-	
+
 	/**
 	 * 查找指定类中的所有字段(包括非public字段),也包括父类和Object类的字段, 字段不存在则返回<code>null</code>
-	 * 
+	 *
 	 * @param beanClass 被查找字段的类,不能为null
-	 * @param name 字段名
+	 * @param name      字段名
 	 * @return 字段
 	 * @throws SecurityException 安全异常
 	 */
@@ -126,7 +135,7 @@ public class ReflectUtil {
 
 	/**
 	 * 获得一个类中所有字段列表,包括其父类中的字段
-	 * 
+	 *
 	 * @param beanClass 类
 	 * @return 字段列表
 	 * @throws SecurityException 安全检查异常
@@ -143,8 +152,8 @@ public class ReflectUtil {
 
 	/**
 	 * 获得一个类中所有字段列表,直接反射获取,无缓存
-	 * 
-	 * @param beanClass 类
+	 *
+	 * @param beanClass           
 	 * @param withSuperClassFieds 是否包括父类的字段列表
 	 * @return 字段列表
 	 * @throws SecurityException 安全检查异常
@@ -170,8 +179,8 @@ public class ReflectUtil {
 
 	/**
 	 * 获取字段值
-	 * 
-	 * @param obj 对象
+	 *
+	 * @param obj       对象
 	 * @param fieldName 字段名
 	 * @return 字段值
 	 * @throws UtilException 包装IllegalAccessException异常
@@ -185,8 +194,8 @@ public class ReflectUtil {
 
 	/**
 	 * 获取字段值
-	 * 
-	 * @param obj 对象
+	 *
+	 * @param obj   对象
 	 * @param field 字段
 	 * @return 字段值
 	 * @throws UtilException 包装IllegalAccessException异常
@@ -195,8 +204,8 @@ public class ReflectUtil {
 		if (null == obj || null == field) {
 			return null;
 		}
-		field.setAccessible(true);
-		Object result = null;
+		setAccessible(field);
+		Object result;
 		try {
 			result = field.get(obj);
 		} catch (IllegalAccessException e) {
@@ -207,6 +216,7 @@ public class ReflectUtil {
 
 	/**
 	 * 获取所有字段的值
+	 *
 	 * @param obj bean对象
 	 * @return 字段值数组
 	 * @since 4.1.17
@@ -227,16 +237,16 @@ public class ReflectUtil {
 
 	/**
 	 * 设置字段值
-	 * 
-	 * @param obj 对象
+	 *
+	 * @param obj       对象
 	 * @param fieldName 字段名
-	 * @param value 值,值类型必须与字段类型匹配,不会自动转换对象类型
+	 * @param value     值,值类型必须与字段类型匹配,不会自动转换对象类型
 	 * @throws UtilException 包装IllegalAccessException异常
 	 */
 	public static void setFieldValue(Object obj, String fieldName, Object value) throws UtilException {
 		Assert.notNull(obj);
 		Assert.notBlank(fieldName);
-		
+
 		final Field field = getField(obj.getClass(), fieldName);
 		Assert.notNull(field, "Field [{}] is not exist in [{}]", fieldName, obj.getClass().getName());
 		setFieldValue(obj, field, value);
@@ -244,8 +254,8 @@ public class ReflectUtil {
 
 	/**
 	 * 设置字段值
-	 * 
-	 * @param obj 对象
+	 *
+	 * @param obj   对象
 	 * @param field 字段
 	 * @param value 值,值类型必须与字段类型匹配,不会自动转换对象类型
 	 * @throws UtilException UtilException 包装IllegalAccessException异常
@@ -253,19 +263,20 @@ public class ReflectUtil {
 	public static void setFieldValue(Object obj, Field field, Object value) throws UtilException {
 		Assert.notNull(obj);
 		Assert.notNull(field, "Field in [{}] not exist !", obj.getClass().getName());
-		field.setAccessible(true);
-		
-		if(null != value) {
+
+		setAccessible(field);
+
+		if (null != value) {
 			Class<?> fieldType = field.getType();
-			if(false == fieldType.isAssignableFrom(value.getClass())) {
+			if (false == fieldType.isAssignableFrom(value.getClass())) {
 				//对于类型不同的字段,尝试转换,转换失败则使用原对象类型
 				final Object targetValue = Convert.convert(fieldType, value);
-				if(null != targetValue) {
+				if (null != targetValue) {
 					value = targetValue;
 				}
 			}
 		}
-		
+
 		try {
 			field.set(obj, value);
 		} catch (IllegalAccessException e) {
@@ -274,17 +285,18 @@ public class ReflectUtil {
 	}
 
 	// --------------------------------------------------------------------------------------------------------- method
+
 	/**
 	 * 获得指定类本类及其父类中的Public方法名<br>
 	 * 去重重载的方法
-	 * 
+	 *
 	 * @param clazz 类
 	 * @return 方法名Set
 	 */
 	public static Set<String> getPublicMethodNames(Class<?> clazz) {
-		final HashSet<String> methodSet = new HashSet<String>();
+		final HashSet<String> methodSet = new HashSet<>();
 		final Method[] methodArray = getPublicMethods(clazz);
-		if(ArrayUtil.isNotEmpty(methodArray)) {
+		if (ArrayUtil.isNotEmpty(methodArray)) {
 			for (Method method : methodArray) {
 				methodSet.add(method.getName());
 			}
@@ -294,7 +306,7 @@ public class ReflectUtil {
 
 	/**
 	 * 获得本类及其父类所有Public方法
-	 * 
+	 *
 	 * @param clazz 查找方法的类
 	 * @return 过滤后的方法列表
 	 */
@@ -304,8 +316,8 @@ public class ReflectUtil {
 
 	/**
 	 * 获得指定类过滤后的Public方法列表
-	 * 
-	 * @param clazz 查找方法的类
+	 *
+	 * @param clazz  查找方法的类
 	 * @param filter 过滤器
 	 * @return 过滤后的方法列表
 	 */
@@ -331,8 +343,8 @@ public class ReflectUtil {
 
 	/**
 	 * 获得指定类过滤后的Public方法列表
-	 * 
-	 * @param clazz 查找方法的类
+	 *
+	 * @param clazz          查找方法的类
 	 * @param excludeMethods 不包括的方法
 	 * @return 过滤后的方法列表
 	 */
@@ -348,8 +360,8 @@ public class ReflectUtil {
 
 	/**
 	 * 获得指定类过滤后的Public方法列表
-	 * 
-	 * @param clazz 查找方法的类
+	 *
+	 * @param clazz              查找方法的类
 	 * @param excludeMethodNames 不包括的方法名列表
 	 * @return 过滤后的方法列表
 	 */
@@ -365,8 +377,8 @@ public class ReflectUtil {
 
 	/**
 	 * 查找指定Public方法 如果找不到对应的方法或方法不为public的则返回<code>null</code>
-	 * 
-	 * @param clazz 类
+	 *
+	 * @param clazz      
 	 * @param methodName 方法名
 	 * @param paramTypes 参数类型
 	 * @return 方法
@@ -379,17 +391,17 @@ public class ReflectUtil {
 			return null;
 		}
 	}
-	
+
 	/**
 	 * 查找指定对象中的所有方法(包括非public方法),也包括父对象和Object类的方法
-	 * 
+	 *
 	 * <p>
 	 * 此方法为精准获取方法名,即方法名和参数数量和类型必须一致,否则返回<code>null</code>。
 	 * </p>
-	 * 
-	 * @param obj 被查找的对象,如果为{@code null}返回{@code null}
+	 *
+	 * @param obj        被查找的对象,如果为{@code null}返回{@code null}
 	 * @param methodName 方法名,如果为空字符串返回{@code null}
-	 * @param args 参数
+	 * @param args       参数
 	 * @return 方法
 	 * @throws SecurityException 无访问权限抛出异常
 	 */
@@ -402,12 +414,12 @@ public class ReflectUtil {
 
 	/**
 	 * 忽略大小写查找指定方法,如果找不到对应的方法则返回<code>null</code>
-	 * 
+	 *
 	 * <p>
 	 * 此方法为精准获取方法名,即方法名和参数数量和类型必须一致,否则返回<code>null</code>。
 	 * </p>
-	 * 
-	 * @param clazz 类,如果为{@code null}返回{@code null}
+	 *
+	 * @param clazz      类,如果为{@code null}返回{@code null}
 	 * @param methodName 方法名,如果为空字符串返回{@code null}
 	 * @param paramTypes 参数类型,指定参数类型如果是方法的子类也算
 	 * @return 方法
@@ -420,12 +432,12 @@ public class ReflectUtil {
 
 	/**
 	 * 查找指定方法 如果找不到对应的方法则返回<code>null</code>
-	 * 
+	 *
 	 * <p>
 	 * 此方法为精准获取方法名,即方法名和参数数量和类型必须一致,否则返回<code>null</code>。
 	 * </p>
-	 * 
-	 * @param clazz 类,如果为{@code null}返回{@code null}
+	 *
+	 * @param clazz      类,如果为{@code null}返回{@code null}
 	 * @param methodName 方法名,如果为空字符串返回{@code null}
 	 * @param paramTypes 参数类型,指定参数类型如果是方法的子类也算
 	 * @return 方法
@@ -437,12 +449,12 @@ public class ReflectUtil {
 
 	/**
 	 * 查找指定方法 如果找不到对应的方法则返回<code>null</code>
-	 * 
+	 *
 	 * <p>
 	 * 此方法为精准获取方法名,即方法名和参数数量和类型必须一致,否则返回<code>null</code>。
 	 * </p>
-	 * 
-	 * @param clazz 类,如果为{@code null}返回{@code null}
+	 *
+	 * @param clazz      类,如果为{@code null}返回{@code null}
 	 * @param ignoreCase 是否忽略大小写
 	 * @param methodName 方法名,如果为空字符串返回{@code null}
 	 * @param paramTypes 参数类型,指定参数类型如果是方法的子类也算
@@ -467,15 +479,15 @@ public class ReflectUtil {
 		}
 		return null;
 	}
-	
+
 	/**
 	 * 按照方法名查找指定方法名的方法,只返回匹配到的第一个方法,如果找不到对应的方法则返回<code>null</code>
-	 * 
+	 *
 	 * <p>
 	 * 此方法只检查方法名是否一致,并不检查参数的一致性。
 	 * </p>
-	 * 
-	 * @param clazz 类,如果为{@code null}返回{@code null}
+	 *
+	 * @param clazz      类,如果为{@code null}返回{@code null}
 	 * @param methodName 方法名,如果为空字符串返回{@code null}
 	 * @return 方法
 	 * @throws SecurityException 无权访问抛出异常
@@ -484,15 +496,15 @@ public class ReflectUtil {
 	public static Method getMethodByName(Class<?> clazz, String methodName) throws SecurityException {
 		return getMethodByName(clazz, false, methodName);
 	}
-	
+
 	/**
 	 * 按照方法名查找指定方法名的方法,只返回匹配到的第一个方法,如果找不到对应的方法则返回<code>null</code>
-	 * 
+	 *
 	 * <p>
 	 * 此方法只检查方法名是否一致(忽略大小写),并不检查参数的一致性。
 	 * </p>
-	 * 
-	 * @param clazz 类,如果为{@code null}返回{@code null}
+	 *
+	 * @param clazz      类,如果为{@code null}返回{@code null}
 	 * @param methodName 方法名,如果为空字符串返回{@code null}
 	 * @return 方法
 	 * @throws SecurityException 无权访问抛出异常
@@ -501,15 +513,15 @@ public class ReflectUtil {
 	public static Method getMethodByNameIgnoreCase(Class<?> clazz, String methodName) throws SecurityException {
 		return getMethodByName(clazz, true, methodName);
 	}
-	
+
 	/**
 	 * 按照方法名查找指定方法名的方法,只返回匹配到的第一个方法,如果找不到对应的方法则返回<code>null</code>
-	 * 
+	 *
 	 * <p>
 	 * 此方法只检查方法名是否一致,并不检查参数的一致性。
 	 * </p>
-	 * 
-	 * @param clazz 类,如果为{@code null}返回{@code null}
+	 *
+	 * @param clazz      类,如果为{@code null}返回{@code null}
 	 * @param ignoreCase 是否忽略大小写
 	 * @param methodName 方法名,如果为空字符串返回{@code null}
 	 * @return 方法
@@ -535,13 +547,13 @@ public class ReflectUtil {
 	/**
 	 * 获得指定类中的Public方法名<br>
 	 * 去重重载的方法
-	 * 
+	 *
 	 * @param clazz 类
 	 * @return 方法名Set
 	 * @throws SecurityException 安全异常
 	 */
 	public static Set<String> getMethodNames(Class<?> clazz) throws SecurityException {
-		final HashSet<String> methodSet = new HashSet<String>();
+		final HashSet<String> methodSet = new HashSet<>();
 		final Method[] methods = getMethods(clazz);
 		for (Method method : methods) {
 			methodSet.add(method.getName());
@@ -551,8 +563,8 @@ public class ReflectUtil {
 
 	/**
 	 * 获得指定类过滤后的Public方法列表
-	 * 
-	 * @param clazz 查找方法的类
+	 *
+	 * @param clazz  查找方法的类
 	 * @param filter 过滤器
 	 * @return 过滤后的方法列表
 	 * @throws SecurityException 安全异常
@@ -566,7 +578,7 @@ public class ReflectUtil {
 
 	/**
 	 * 获得一个类中所有方法列表,包括其父类中的方法
-	 * 
+	 *
 	 * @param beanClass 类
 	 * @return 方法列表
 	 * @throws SecurityException 安全检查异常
@@ -583,8 +595,8 @@ public class ReflectUtil {
 
 	/**
 	 * 获得一个类中所有方法列表,直接反射获取,无缓存
-	 * 
-	 * @param beanClass 类
+	 *
+	 * @param beanClass             
 	 * @param withSuperClassMethods 是否包括父类的方法列表
 	 * @return 方法列表
 	 * @throws SecurityException 安全检查异常
@@ -610,7 +622,7 @@ public class ReflectUtil {
 
 	/**
 	 * 是否为equals方法
-	 * 
+	 *
 	 * @param method 方法
 	 * @return 是否为equals方法
 	 */
@@ -624,7 +636,7 @@ public class ReflectUtil {
 
 	/**
 	 * 是否为hashCode方法
-	 * 
+	 *
 	 * @param method 方法
 	 * @return 是否为hashCode方法
 	 */
@@ -634,7 +646,7 @@ public class ReflectUtil {
 
 	/**
 	 * 是否为toString方法
-	 * 
+	 *
 	 * @param method 方法
 	 * @return 是否为toString方法
 	 */
@@ -643,10 +655,11 @@ public class ReflectUtil {
 	}
 
 	// --------------------------------------------------------------------------------------------------------- newInstance
+
 	/**
 	 * 实例化对象
-	 * 
-	 * @param <T> 对象类型
+	 *
+	 * @param <T>   对象类型
 	 * @param clazz 类名
 	 * @return 对象
 	 * @throws UtilException 包装各类异常
@@ -662,9 +675,9 @@ public class ReflectUtil {
 
 	/**
 	 * 实例化对象
-	 * 
-	 * @param <T> 对象类型
-	 * @param clazz 类
+	 *
+	 * @param <T>    对象类型
+	 * @param clazz  
 	 * @param params 构造函数参数
 	 * @return 对象
 	 * @throws UtilException 包装各类异常
@@ -682,7 +695,7 @@ public class ReflectUtil {
 		final Class<?>[] paramTypes = ClassUtil.getClasses(params);
 		final Constructor<T> constructor = getConstructor(clazz, paramTypes);
 		if (null == constructor) {
-			throw new UtilException("No Constructor matched for parameter types: [{}]", new Object[] { paramTypes });
+			throw new UtilException("No Constructor matched for parameter types: [{}]", new Object[]{paramTypes});
 		}
 		try {
 			return constructor.newInstance(params);
@@ -693,8 +706,8 @@ public class ReflectUtil {
 
 	/**
 	 * 尝试遍历并调用此类的所有构造方法,直到构造成功并返回
-	 * 
-	 * @param <T> 对象类型
+	 *
+	 * @param <T>       对象类型
 	 * @param beanClass 被构造的类
 	 * @return 构造后的对象
 	 */
@@ -706,7 +719,7 @@ public class ReflectUtil {
 			// ignore
 			// 默认构造不存在的情况下查找其它构造
 		}
-		
+
 		final Constructor<T>[] constructors = getConstructors(beanClass);
 		Class<?>[] parameterTypes;
 		for (Constructor<T> constructor : constructors) {
@@ -714,24 +727,24 @@ public class ReflectUtil {
 			if (0 == parameterTypes.length) {
 				continue;
 			}
-			constructor.setAccessible(true);
+			setAccessible(constructor);
 			try {
 				return constructor.newInstance(ClassUtil.getDefaultValues(parameterTypes));
-			} catch (Exception e) {
+			} catch (Exception ignore) {
 				// 构造出错时继续尝试下一种构造方式
-				continue;
 			}
 		}
 		return null;
 	}
 
 	// --------------------------------------------------------------------------------------------------------- invoke
+
 	/**
 	 * 执行静态方法
-	 * 
-	 * @param <T> 对象类型
+	 *
+	 * @param <T>    对象类型
 	 * @param method 方法(对象方法或static方法都可)
-	 * @param args 参数对象
+	 * @param args   参数对象
 	 * @return 结果
 	 * @throws UtilException 多种异常包装
 	 */
@@ -742,16 +755,16 @@ public class ReflectUtil {
 	/**
 	 * 执行方法<br>
 	 * 执行前要检查给定参数:
-	 * 
+	 *
 	 * <pre>
 	 * 1. 参数个数是否与方法参数个数一致
 	 * 2. 如果某个参数为null但是方法这个位置的参数为原始类型,则赋予原始类型默认值
 	 * </pre>
-	 * 
-	 * @param <T> 返回对象类型
-	 * @param obj 对象,如果执行静态方法,此值为<code>null</code>
+	 *
+	 * @param <T>    返回对象类型
+	 * @param obj    对象,如果执行静态方法,此值为<code>null</code>
 	 * @param method 方法(对象方法或static方法都可)
-	 * @param args 参数对象
+	 * @param args   参数对象
 	 * @return 结果
 	 * @throws UtilException 一些列异常的包装
 	 */
@@ -774,19 +787,17 @@ public class ReflectUtil {
 
 	/**
 	 * 执行方法
-	 * 
-	 * @param <T> 返回对象类型
-	 * @param obj 对象,如果执行静态方法,此值为<code>null</code>
+	 *
+	 * @param <T>    返回对象类型
+	 * @param obj    对象,如果执行静态方法,此值为<code>null</code>
 	 * @param method 方法(对象方法或static方法都可)
-	 * @param args 参数对象
+	 * @param args   参数对象
 	 * @return 结果
 	 * @throws UtilException 一些列异常的包装
 	 */
 	@SuppressWarnings("unchecked")
 	public static <T> T invoke(Object obj, Method method, Object... args) throws UtilException {
-		if (false == method.isAccessible()) {
-			method.setAccessible(true);
-		}
+		setAccessible(method);
 
 		try {
 			return (T) method.invoke(ClassUtil.isStatic(method) ? null : obj, args);
@@ -797,11 +808,11 @@ public class ReflectUtil {
 
 	/**
 	 * 执行对象中指定方法
-	 * 
-	 * @param <T> 返回对象类型
-	 * @param obj 方法所在对象
+	 *
+	 * @param <T>        返回对象类型
+	 * @param obj        方法所在对象
 	 * @param methodName 方法名
-	 * @param args 参数列表
+	 * @param args       参数列表
 	 * @return 执行结果
 	 * @throws UtilException IllegalAccessException包装
 	 * @since 3.1.2
@@ -813,4 +824,18 @@ public class ReflectUtil {
 		}
 		return invoke(obj, method, args);
 	}
+
+	/**
+	 * 设置方法为可访问(私有方法可以被外部调用)
+	 *
+	 * @param <T>              AccessibleObject的子类,比如Class、Method、Field等
+	 * @param accessibleObject 可设置访问权限的对象,比如Class、Method、Field等
+	 * @since 4.6.8
+	 */
+	public static <T extends AccessibleObject> T setAccessible(T accessibleObject) {
+		if (null != accessibleObject && false == accessibleObject.isAccessible()) {
+			accessibleObject.setAccessible(true);
+		}
+		return accessibleObject;
+	}
 }