mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
change line sep
This commit is contained in:
@@ -1,74 +1,74 @@
|
||||
package cn.hutool.aop;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import cn.hutool.aop.proxy.ProxyFactory;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
|
||||
/**
|
||||
* 代理工具类
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public final class ProxyUtil {
|
||||
|
||||
/**
|
||||
* 使用切面代理对象
|
||||
*
|
||||
* @param <T> 切面对象类型
|
||||
* @param target 目标对象
|
||||
* @param aspectClass 切面对象类
|
||||
* @return 代理对象
|
||||
*/
|
||||
public static <T> T proxy(T target, Class<? extends Aspect> aspectClass){
|
||||
return ProxyFactory.createProxy(target, aspectClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用切面代理对象
|
||||
*
|
||||
* @param <T> 被代理对象类型
|
||||
* @param target 被代理对象
|
||||
* @param aspect 切面对象
|
||||
* @return 代理对象
|
||||
*/
|
||||
public static <T> T proxy(T target, Aspect aspect){
|
||||
return ProxyFactory.createProxy(target, aspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建动态代理对象<br>
|
||||
* 动态代理对象的创建原理是:<br>
|
||||
* 假设创建的代理对象名为 $Proxy0<br>
|
||||
* 1、根据传入的interfaces动态生成一个类,实现interfaces中的接口<br>
|
||||
* 2、通过传入的classloder将刚生成的类加载到jvm中。即将$Proxy0类load<br>
|
||||
* 3、调用$Proxy0的$Proxy0(InvocationHandler)构造函数 创建$Proxy0的对象,并且用interfaces参数遍历其所有接口的方法,这些实现方法的实现本质上是通过反射调用被代理对象的方法<br>
|
||||
* 4、将$Proxy0的实例返回给客户端。 <br>
|
||||
* 5、当调用代理类的相应方法时,相当于调用 {@link InvocationHandler#invoke(Object, java.lang.reflect.Method, Object[])} 方法
|
||||
*
|
||||
*
|
||||
* @param <T> 被代理对象类型
|
||||
* @param classloader 被代理类对应的ClassLoader
|
||||
* @param invocationHandler {@link InvocationHandler} ,被代理类通过实现此接口提供动态代理功能
|
||||
* @param interfaces 代理类中需要实现的被代理类的接口方法
|
||||
* @return 代理类
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T newProxyInstance(ClassLoader classloader, InvocationHandler invocationHandler, Class<?>... interfaces) {
|
||||
return (T) Proxy.newProxyInstance(classloader, interfaces, invocationHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建动态代理对象
|
||||
*
|
||||
* @param <T> 被代理对象类型
|
||||
* @param invocationHandler {@link InvocationHandler} ,被代理类通过实现此接口提供动态代理功能
|
||||
* @param interfaces 代理类中需要实现的被代理类的接口方法
|
||||
* @return 代理类
|
||||
*/
|
||||
public static <T> T newProxyInstance(InvocationHandler invocationHandler, Class<?>... interfaces) {
|
||||
return newProxyInstance(ClassUtil.getClassLoader(), invocationHandler, interfaces);
|
||||
}
|
||||
}
|
||||
package cn.hutool.aop;
|
||||
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Proxy;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import cn.hutool.aop.proxy.ProxyFactory;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
|
||||
/**
|
||||
* 代理工具类
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public final class ProxyUtil {
|
||||
|
||||
/**
|
||||
* 使用切面代理对象
|
||||
*
|
||||
* @param <T> 切面对象类型
|
||||
* @param target 目标对象
|
||||
* @param aspectClass 切面对象类
|
||||
* @return 代理对象
|
||||
*/
|
||||
public static <T> T proxy(T target, Class<? extends Aspect> aspectClass){
|
||||
return ProxyFactory.createProxy(target, aspectClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用切面代理对象
|
||||
*
|
||||
* @param <T> 被代理对象类型
|
||||
* @param target 被代理对象
|
||||
* @param aspect 切面对象
|
||||
* @return 代理对象
|
||||
*/
|
||||
public static <T> T proxy(T target, Aspect aspect){
|
||||
return ProxyFactory.createProxy(target, aspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建动态代理对象<br>
|
||||
* 动态代理对象的创建原理是:<br>
|
||||
* 假设创建的代理对象名为 $Proxy0<br>
|
||||
* 1、根据传入的interfaces动态生成一个类,实现interfaces中的接口<br>
|
||||
* 2、通过传入的classloder将刚生成的类加载到jvm中。即将$Proxy0类load<br>
|
||||
* 3、调用$Proxy0的$Proxy0(InvocationHandler)构造函数 创建$Proxy0的对象,并且用interfaces参数遍历其所有接口的方法,这些实现方法的实现本质上是通过反射调用被代理对象的方法<br>
|
||||
* 4、将$Proxy0的实例返回给客户端。 <br>
|
||||
* 5、当调用代理类的相应方法时,相当于调用 {@link InvocationHandler#invoke(Object, java.lang.reflect.Method, Object[])} 方法
|
||||
*
|
||||
*
|
||||
* @param <T> 被代理对象类型
|
||||
* @param classloader 被代理类对应的ClassLoader
|
||||
* @param invocationHandler {@link InvocationHandler} ,被代理类通过实现此接口提供动态代理功能
|
||||
* @param interfaces 代理类中需要实现的被代理类的接口方法
|
||||
* @return 代理类
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T newProxyInstance(ClassLoader classloader, InvocationHandler invocationHandler, Class<?>... interfaces) {
|
||||
return (T) Proxy.newProxyInstance(classloader, interfaces, invocationHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建动态代理对象
|
||||
*
|
||||
* @param <T> 被代理对象类型
|
||||
* @param invocationHandler {@link InvocationHandler} ,被代理类通过实现此接口提供动态代理功能
|
||||
* @param interfaces 代理类中需要实现的被代理类的接口方法
|
||||
* @return 代理类
|
||||
*/
|
||||
public static <T> T newProxyInstance(InvocationHandler invocationHandler, Class<?>... interfaces) {
|
||||
return newProxyInstance(ClassUtil.getClassLoader(), invocationHandler, interfaces);
|
||||
}
|
||||
}
|
||||
|
@@ -1,49 +1,49 @@
|
||||
package cn.hutool.aop.aspects;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 切面接口
|
||||
*
|
||||
* @author looly
|
||||
* @author ted.L
|
||||
* @since 4.18
|
||||
*/
|
||||
public interface Aspect {
|
||||
|
||||
/**
|
||||
* 目标方法执行前的操作
|
||||
*
|
||||
* @param target 目标对象
|
||||
* @param method 目标方法
|
||||
* @param args 参数
|
||||
* @return 是否继续执行接下来的操作
|
||||
*/
|
||||
boolean before(Object target, Method method, Object[] args);
|
||||
|
||||
/**
|
||||
* 目标方法执行后的操作
|
||||
* 如果 target.method 抛出异常且
|
||||
*
|
||||
* @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 异常
|
||||
* @return 是否允许抛出异常
|
||||
*/
|
||||
boolean afterException(Object target, Method method, Object[] args, Throwable e);
|
||||
}
|
||||
package cn.hutool.aop.aspects;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 切面接口
|
||||
*
|
||||
* @author looly
|
||||
* @author ted.L
|
||||
* @since 4.18
|
||||
*/
|
||||
public interface Aspect {
|
||||
|
||||
/**
|
||||
* 目标方法执行前的操作
|
||||
*
|
||||
* @param target 目标对象
|
||||
* @param method 目标方法
|
||||
* @param args 参数
|
||||
* @return 是否继续执行接下来的操作
|
||||
*/
|
||||
boolean before(Object target, Method method, Object[] args);
|
||||
|
||||
/**
|
||||
* 目标方法执行后的操作
|
||||
* 如果 target.method 抛出异常且
|
||||
*
|
||||
* @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 异常
|
||||
* @return 是否允许抛出异常
|
||||
*/
|
||||
boolean afterException(Object target, Method method, Object[] args, Throwable e);
|
||||
}
|
||||
|
@@ -1,33 +1,33 @@
|
||||
package cn.hutool.aop.aspects;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 简单切面类,不做任何操作<br>
|
||||
* 可以继承此类实现自己需要的方法即可
|
||||
*
|
||||
* @author Looly, ted.L
|
||||
*/
|
||||
public class SimpleAspect implements Aspect, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean before(Object target, Method method, Object[] args) {
|
||||
//继承此类后实现此方法
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean after(Object target, Method method, Object[] args, Object returnVal) {
|
||||
//继承此类后实现此方法
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean afterException(Object target, Method method, Object[] args, Throwable e) {
|
||||
//继承此类后实现此方法
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
package cn.hutool.aop.aspects;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 简单切面类,不做任何操作<br>
|
||||
* 可以继承此类实现自己需要的方法即可
|
||||
*
|
||||
* @author Looly, ted.L
|
||||
*/
|
||||
public class SimpleAspect implements Aspect, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public boolean before(Object target, Method method, Object[] args) {
|
||||
//继承此类后实现此方法
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean after(Object target, Method method, Object[] args, Object returnVal) {
|
||||
//继承此类后实现此方法
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean afterException(Object target, Method method, Object[] args, Throwable e) {
|
||||
//继承此类后实现此方法
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,33 +1,33 @@
|
||||
package cn.hutool.aop.aspects;
|
||||
|
||||
import cn.hutool.core.date.TimeInterval;
|
||||
import cn.hutool.core.lang.Console;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 通过日志打印方法的执行时间的切面
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public class TimeIntervalAspect extends SimpleAspect {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final TimeInterval interval = new TimeInterval();
|
||||
|
||||
@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(), //
|
||||
returnVal);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package cn.hutool.aop.aspects;
|
||||
|
||||
import cn.hutool.core.date.TimeInterval;
|
||||
import cn.hutool.core.lang.Console;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* 通过日志打印方法的执行时间的切面
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public class TimeIntervalAspect extends SimpleAspect {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final TimeInterval interval = new TimeInterval();
|
||||
|
||||
@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(), //
|
||||
returnVal);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* 切面实现,提供一些基本的切面实现
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* 切面实现,提供一些基本的切面实现
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
package cn.hutool.aop.aspects;
|
@@ -1,60 +1,60 @@
|
||||
package cn.hutool.aop.interceptor;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
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, ted.L
|
||||
*/
|
||||
public class CglibInterceptor implements MethodInterceptor, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Object target;
|
||||
private final Aspect aspect;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param target 被代理对象
|
||||
* @param aspect 切面实现
|
||||
*/
|
||||
public CglibInterceptor(Object target, Aspect aspect) {
|
||||
this.target = target;
|
||||
this.aspect = aspect;
|
||||
}
|
||||
|
||||
public Object getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
|
||||
final Object target = this.target;
|
||||
Object result = null;
|
||||
// 开始前回调
|
||||
if (aspect.before(target, method, args)) {
|
||||
try {
|
||||
// result = proxy.invokeSuper(obj, args);
|
||||
result = proxy.invoke(target, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
// 异常回调(只捕获业务代码导致的异常,而非反射导致的异常)
|
||||
if (aspect.afterException(target, method, args, e.getTargetException())) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 结束执行回调
|
||||
if (aspect.after(target, method, args, result)) {
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
package cn.hutool.aop.interceptor;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
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, ted.L
|
||||
*/
|
||||
public class CglibInterceptor implements MethodInterceptor, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Object target;
|
||||
private final Aspect aspect;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param target 被代理对象
|
||||
* @param aspect 切面实现
|
||||
*/
|
||||
public CglibInterceptor(Object target, Aspect aspect) {
|
||||
this.target = target;
|
||||
this.aspect = aspect;
|
||||
}
|
||||
|
||||
public Object getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
|
||||
final Object target = this.target;
|
||||
Object result = null;
|
||||
// 开始前回调
|
||||
if (aspect.before(target, method, args)) {
|
||||
try {
|
||||
// result = proxy.invokeSuper(obj, args);
|
||||
result = proxy.invoke(target, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
// 异常回调(只捕获业务代码导致的异常,而非反射导致的异常)
|
||||
if (aspect.afterException(target, method, args, e.getTargetException())) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 结束执行回调
|
||||
if (aspect.after(target, method, args, result)) {
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -1,66 +1,66 @@
|
||||
package cn.hutool.aop.interceptor;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* JDK实现的动态代理切面
|
||||
*
|
||||
* @author Looly
|
||||
* @author ted.L
|
||||
*/
|
||||
public class JdkInterceptor implements InvocationHandler, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Object target;
|
||||
private final Aspect aspect;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param target 被代理对象
|
||||
* @param aspect 切面实现
|
||||
*/
|
||||
public JdkInterceptor(Object target, Aspect aspect) {
|
||||
this.target = target;
|
||||
this.aspect = aspect;
|
||||
}
|
||||
|
||||
public Object getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
final Object target = this.target;
|
||||
final Aspect aspect = this.aspect;
|
||||
Object result = null;
|
||||
|
||||
// 开始前回调
|
||||
if (aspect.before(target, method, args)) {
|
||||
ReflectUtil.setAccessible(method);
|
||||
|
||||
try {
|
||||
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;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
package cn.hutool.aop.interceptor;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import cn.hutool.core.util.ClassUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* JDK实现的动态代理切面
|
||||
*
|
||||
* @author Looly
|
||||
* @author ted.L
|
||||
*/
|
||||
public class JdkInterceptor implements InvocationHandler, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Object target;
|
||||
private final Aspect aspect;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param target 被代理对象
|
||||
* @param aspect 切面实现
|
||||
*/
|
||||
public JdkInterceptor(Object target, Aspect aspect) {
|
||||
this.target = target;
|
||||
this.aspect = aspect;
|
||||
}
|
||||
|
||||
public Object getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
|
||||
final Object target = this.target;
|
||||
final Aspect aspect = this.aspect;
|
||||
Object result = null;
|
||||
|
||||
// 开始前回调
|
||||
if (aspect.before(target, method, args)) {
|
||||
ReflectUtil.setAccessible(method);
|
||||
|
||||
try {
|
||||
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;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,65 +1,65 @@
|
||||
package cn.hutool.aop.interceptor;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import org.springframework.cglib.proxy.MethodInterceptor;
|
||||
import org.springframework.cglib.proxy.MethodProxy;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Spring-cglib实现的动态代理切面
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public class SpringCglibInterceptor implements MethodInterceptor, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Object target;
|
||||
private final Aspect aspect;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param target 被代理对象
|
||||
* @param aspect 切面实现
|
||||
*/
|
||||
public SpringCglibInterceptor(Object target, Aspect aspect) {
|
||||
this.target = target;
|
||||
this.aspect = aspect;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得目标对象
|
||||
*
|
||||
* @return 目标对象
|
||||
*/
|
||||
public Object getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
|
||||
final Object target = this.target;
|
||||
Object result = null;
|
||||
// 开始前回调
|
||||
if (aspect.before(target, method, args)) {
|
||||
try {
|
||||
// result = proxy.invokeSuper(obj, args);
|
||||
result = proxy.invoke(target, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
// 异常回调(只捕获业务代码导致的异常,而非反射导致的异常)
|
||||
if (aspect.afterException(target, method, args, e.getTargetException())) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 结束执行回调
|
||||
if (aspect.after(target, method, args, result)) {
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
package cn.hutool.aop.interceptor;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import org.springframework.cglib.proxy.MethodInterceptor;
|
||||
import org.springframework.cglib.proxy.MethodProxy;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* Spring-cglib实现的动态代理切面
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public class SpringCglibInterceptor implements MethodInterceptor, Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final Object target;
|
||||
private final Aspect aspect;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param target 被代理对象
|
||||
* @param aspect 切面实现
|
||||
*/
|
||||
public SpringCglibInterceptor(Object target, Aspect aspect) {
|
||||
this.target = target;
|
||||
this.aspect = aspect;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获得目标对象
|
||||
*
|
||||
* @return 目标对象
|
||||
*/
|
||||
public Object getTarget() {
|
||||
return this.target;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
|
||||
final Object target = this.target;
|
||||
Object result = null;
|
||||
// 开始前回调
|
||||
if (aspect.before(target, method, args)) {
|
||||
try {
|
||||
// result = proxy.invokeSuper(obj, args);
|
||||
result = proxy.invoke(target, args);
|
||||
} catch (InvocationTargetException e) {
|
||||
// 异常回调(只捕获业务代码导致的异常,而非反射导致的异常)
|
||||
if (aspect.afterException(target, method, args, e.getTargetException())) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 结束执行回调
|
||||
if (aspect.after(target, method, args, result)) {
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* 代理拦截器实现
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* 代理拦截器实现
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
package cn.hutool.aop.interceptor;
|
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* JDK动态代理封装,提供非IOC下的切面支持
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* JDK动态代理封装,提供非IOC下的切面支持
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
package cn.hutool.aop;
|
@@ -1,25 +1,25 @@
|
||||
package cn.hutool.aop.proxy;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import cn.hutool.aop.interceptor.CglibInterceptor;
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
|
||||
/**
|
||||
* 基于Cglib的切面代理工厂
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
public class CglibProxyFactory extends ProxyFactory{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T proxy(T target, Aspect aspect) {
|
||||
final Enhancer enhancer = new Enhancer();
|
||||
enhancer.setSuperclass(target.getClass());
|
||||
enhancer.setCallback(new CglibInterceptor(target, aspect));
|
||||
return (T) enhancer.create();
|
||||
}
|
||||
|
||||
}
|
||||
package cn.hutool.aop.proxy;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import cn.hutool.aop.interceptor.CglibInterceptor;
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
|
||||
/**
|
||||
* 基于Cglib的切面代理工厂
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
public class CglibProxyFactory extends ProxyFactory{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T proxy(T target, Aspect aspect) {
|
||||
final Enhancer enhancer = new Enhancer();
|
||||
enhancer.setSuperclass(target.getClass());
|
||||
enhancer.setCallback(new CglibInterceptor(target, aspect));
|
||||
return (T) enhancer.create();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,22 +1,22 @@
|
||||
package cn.hutool.aop.proxy;
|
||||
|
||||
import cn.hutool.aop.ProxyUtil;
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import cn.hutool.aop.interceptor.JdkInterceptor;
|
||||
|
||||
/**
|
||||
* JDK实现的切面代理
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public class JdkProxyFactory extends ProxyFactory {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public <T> T proxy(T target, Aspect aspect) {
|
||||
return ProxyUtil.newProxyInstance(//
|
||||
target.getClass().getClassLoader(), //
|
||||
new JdkInterceptor(target, aspect), //
|
||||
target.getClass().getInterfaces());
|
||||
}
|
||||
}
|
||||
package cn.hutool.aop.proxy;
|
||||
|
||||
import cn.hutool.aop.ProxyUtil;
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import cn.hutool.aop.interceptor.JdkInterceptor;
|
||||
|
||||
/**
|
||||
* JDK实现的切面代理
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public class JdkProxyFactory extends ProxyFactory {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public <T> T proxy(T target, Aspect aspect) {
|
||||
return ProxyUtil.newProxyInstance(//
|
||||
target.getClass().getClassLoader(), //
|
||||
new JdkInterceptor(target, aspect), //
|
||||
target.getClass().getInterfaces());
|
||||
}
|
||||
}
|
||||
|
@@ -1,73 +1,73 @@
|
||||
package cn.hutool.aop.proxy;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.ServiceLoaderUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 代理工厂<br>
|
||||
* 根据用户引入代理库的不同,产生不同的代理对象
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public abstract class ProxyFactory implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 创建代理
|
||||
*
|
||||
* @param <T> 代理对象类型
|
||||
* @param target 被代理对象
|
||||
* @param aspectClass 切面实现类,自动实例化
|
||||
* @return 代理对象
|
||||
* @since 5.3.1
|
||||
*/
|
||||
public <T> T proxy(T target, Class<? extends Aspect> aspectClass) {
|
||||
return proxy(target, ReflectUtil.newInstanceIfPossible(aspectClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建代理
|
||||
*
|
||||
* @param <T> 代理对象类型
|
||||
* @param target 被代理对象
|
||||
* @param aspect 切面实现
|
||||
* @return 代理对象
|
||||
*/
|
||||
public abstract <T> T proxy(T target, Aspect aspect);
|
||||
|
||||
/**
|
||||
* 根据用户引入Cglib与否自动创建代理对象
|
||||
*
|
||||
* @param <T> 切面对象类型
|
||||
* @param target 目标对象
|
||||
* @param aspectClass 切面对象类
|
||||
* @return 代理对象
|
||||
*/
|
||||
public static <T> T createProxy(T target, Class<? extends Aspect> aspectClass) {
|
||||
return createProxy(target, ReflectUtil.newInstance(aspectClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户引入Cglib与否自动创建代理对象
|
||||
*
|
||||
* @param <T> 切面对象类型
|
||||
* @param target 被代理对象
|
||||
* @param aspect 切面实现
|
||||
* @return 代理对象
|
||||
*/
|
||||
public static <T> T createProxy(T target, Aspect aspect) {
|
||||
return create().proxy(target, aspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户引入Cglib与否创建代理工厂
|
||||
*
|
||||
* @return 代理工厂
|
||||
*/
|
||||
public static ProxyFactory create() {
|
||||
return ServiceLoaderUtil.loadFirstAvailable(ProxyFactory.class);
|
||||
}
|
||||
}
|
||||
package cn.hutool.aop.proxy;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.core.util.ServiceLoaderUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 代理工厂<br>
|
||||
* 根据用户引入代理库的不同,产生不同的代理对象
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public abstract class ProxyFactory implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 创建代理
|
||||
*
|
||||
* @param <T> 代理对象类型
|
||||
* @param target 被代理对象
|
||||
* @param aspectClass 切面实现类,自动实例化
|
||||
* @return 代理对象
|
||||
* @since 5.3.1
|
||||
*/
|
||||
public <T> T proxy(T target, Class<? extends Aspect> aspectClass) {
|
||||
return proxy(target, ReflectUtil.newInstanceIfPossible(aspectClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建代理
|
||||
*
|
||||
* @param <T> 代理对象类型
|
||||
* @param target 被代理对象
|
||||
* @param aspect 切面实现
|
||||
* @return 代理对象
|
||||
*/
|
||||
public abstract <T> T proxy(T target, Aspect aspect);
|
||||
|
||||
/**
|
||||
* 根据用户引入Cglib与否自动创建代理对象
|
||||
*
|
||||
* @param <T> 切面对象类型
|
||||
* @param target 目标对象
|
||||
* @param aspectClass 切面对象类
|
||||
* @return 代理对象
|
||||
*/
|
||||
public static <T> T createProxy(T target, Class<? extends Aspect> aspectClass) {
|
||||
return createProxy(target, ReflectUtil.newInstance(aspectClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户引入Cglib与否自动创建代理对象
|
||||
*
|
||||
* @param <T> 切面对象类型
|
||||
* @param target 被代理对象
|
||||
* @param aspect 切面实现
|
||||
* @return 代理对象
|
||||
*/
|
||||
public static <T> T createProxy(T target, Aspect aspect) {
|
||||
return create().proxy(target, aspect);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户引入Cglib与否创建代理工厂
|
||||
*
|
||||
* @return 代理工厂
|
||||
*/
|
||||
public static ProxyFactory create() {
|
||||
return ServiceLoaderUtil.loadFirstAvailable(ProxyFactory.class);
|
||||
}
|
||||
}
|
||||
|
@@ -1,25 +1,25 @@
|
||||
package cn.hutool.aop.proxy;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import cn.hutool.aop.interceptor.SpringCglibInterceptor;
|
||||
import org.springframework.cglib.proxy.Enhancer;
|
||||
|
||||
/**
|
||||
* 基于Spring-cglib的切面代理工厂
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
public class SpringCglibProxyFactory extends ProxyFactory{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T proxy(T target, Aspect aspect) {
|
||||
final Enhancer enhancer = new Enhancer();
|
||||
enhancer.setSuperclass(target.getClass());
|
||||
enhancer.setCallback(new SpringCglibInterceptor(target, aspect));
|
||||
return (T) enhancer.create();
|
||||
}
|
||||
|
||||
}
|
||||
package cn.hutool.aop.proxy;
|
||||
|
||||
import cn.hutool.aop.aspects.Aspect;
|
||||
import cn.hutool.aop.interceptor.SpringCglibInterceptor;
|
||||
import org.springframework.cglib.proxy.Enhancer;
|
||||
|
||||
/**
|
||||
* 基于Spring-cglib的切面代理工厂
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
public class SpringCglibProxyFactory extends ProxyFactory{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T proxy(T target, Aspect aspect) {
|
||||
final Enhancer enhancer = new Enhancer();
|
||||
enhancer.setSuperclass(target.getClass());
|
||||
enhancer.setCallback(new SpringCglibInterceptor(target, aspect));
|
||||
return (T) enhancer.create();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* 代理实现
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* 代理实现
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
package cn.hutool.aop.proxy;
|
@@ -1,3 +1,3 @@
|
||||
cn.hutool.aop.proxy.CglibProxyFactory
|
||||
cn.hutool.aop.proxy.SpringCglibProxyFactory
|
||||
cn.hutool.aop.proxy.CglibProxyFactory
|
||||
cn.hutool.aop.proxy.SpringCglibProxyFactory
|
||||
cn.hutool.aop.proxy.JdkProxyFactory
|
@@ -1,88 +1,88 @@
|
||||
package cn.hutool.aop.test;
|
||||
|
||||
import cn.hutool.aop.ProxyUtil;
|
||||
import cn.hutool.aop.aspects.TimeIntervalAspect;
|
||||
import cn.hutool.core.lang.Console;
|
||||
import lombok.Data;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* AOP模块单元测试
|
||||
*
|
||||
* @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 aopByAutoCglibTest() {
|
||||
Dog dog = ProxyUtil.proxy(new Dog(), TimeIntervalAspect.class);
|
||||
String result = dog.eat();
|
||||
Assert.assertEquals("狗吃肉", result);
|
||||
|
||||
dog.seize();
|
||||
}
|
||||
|
||||
interface Animal {
|
||||
String eat();
|
||||
|
||||
void seize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 有接口
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
static class Cat implements Animal {
|
||||
|
||||
@Override
|
||||
public String eat() {
|
||||
return "猫吃鱼";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seize() {
|
||||
Console.log("抓了条鱼");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 无接口
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
static class Dog {
|
||||
public String eat() {
|
||||
return "狗吃肉";
|
||||
}
|
||||
|
||||
public void seize() {
|
||||
Console.log("抓了只鸡");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCGLIBProxy() {
|
||||
TagObj target = new TagObj();
|
||||
//目标类设置标记
|
||||
target.setTag("tag");
|
||||
|
||||
TagObj proxy = ProxyUtil.proxy(target, TimeIntervalAspect.class);
|
||||
//代理类获取标记tag (断言错误)
|
||||
Assert.assertEquals("tag", proxy.getTag());
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class TagObj{
|
||||
private String tag;
|
||||
}
|
||||
}
|
||||
package cn.hutool.aop.test;
|
||||
|
||||
import cn.hutool.aop.ProxyUtil;
|
||||
import cn.hutool.aop.aspects.TimeIntervalAspect;
|
||||
import cn.hutool.core.lang.Console;
|
||||
import lombok.Data;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* AOP模块单元测试
|
||||
*
|
||||
* @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 aopByAutoCglibTest() {
|
||||
Dog dog = ProxyUtil.proxy(new Dog(), TimeIntervalAspect.class);
|
||||
String result = dog.eat();
|
||||
Assert.assertEquals("狗吃肉", result);
|
||||
|
||||
dog.seize();
|
||||
}
|
||||
|
||||
interface Animal {
|
||||
String eat();
|
||||
|
||||
void seize();
|
||||
}
|
||||
|
||||
/**
|
||||
* 有接口
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
static class Cat implements Animal {
|
||||
|
||||
@Override
|
||||
public String eat() {
|
||||
return "猫吃鱼";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seize() {
|
||||
Console.log("抓了条鱼");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 无接口
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
static class Dog {
|
||||
public String eat() {
|
||||
return "狗吃肉";
|
||||
}
|
||||
|
||||
public void seize() {
|
||||
Console.log("抓了只鸡");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCGLIBProxy() {
|
||||
TagObj target = new TagObj();
|
||||
//目标类设置标记
|
||||
target.setTag("tag");
|
||||
|
||||
TagObj proxy = ProxyUtil.proxy(target, TimeIntervalAspect.class);
|
||||
//代理类获取标记tag (断言错误)
|
||||
Assert.assertEquals("tag", proxy.getTag());
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class TagObj{
|
||||
private String tag;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user