mirror of
https://gitee.com/dromara/hutool.git
synced 2025-05-03 12:18:01 +08:00
Merge pull request #561 from Ted-Engineer/v4-dev
1、切面after切点,将目标方法执行返回值,开放给切点 2、SimpleAspect没有直接使用的意义,应修改为抽象类 3、修改Aspect#afterException 没有使用返回值进行异常是否抛出的判断。 4、修改CglibInterceptor#intercept 和 JdkInterceptor#intercept 方法中 if else 为 if ,减少else判断,并支持 第3点的修改
This commit is contained in:
commit
5b5645cbbb
@ -6,6 +6,7 @@ import java.lang.reflect.Method;
|
||||
* 切面接口
|
||||
*
|
||||
* @author looly
|
||||
* @author ted.L
|
||||
* @since 4.18
|
||||
*/
|
||||
public interface Aspect{
|
||||
@ -22,13 +23,18 @@ public interface Aspect{
|
||||
|
||||
/**
|
||||
* 目标方法执行后的操作
|
||||
*
|
||||
* 如果 target.method 抛出异常且
|
||||
* @see Aspect#afterException 返回true,则不会执行此操作
|
||||
* 如果
|
||||
* @see Aspect#afterException 返回false,则无论target.method是否抛出异常,均会执行此操作
|
||||
*
|
||||
* @param target 目标对象
|
||||
* @param method 目标方法
|
||||
* @param args 参数
|
||||
* @param returnVal 目标方法执行返回值
|
||||
* @return 是否允许返回值(接下来的操作)
|
||||
*/
|
||||
boolean after(Object target, Method method, Object[] args);
|
||||
boolean after(Object target, Method method, Object[] args, Object returnVal);
|
||||
|
||||
/**
|
||||
* 目标方法抛出异常时的操作
|
||||
|
@ -8,23 +8,36 @@ import java.lang.reflect.Method;
|
||||
* 可以继承此类实现自己需要的方法即可
|
||||
*
|
||||
* @author Looly
|
||||
* @author ted.L
|
||||
*
|
||||
*/
|
||||
public class SimpleAspect implements Aspect, Serializable{
|
||||
public abstract 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
|
||||
*/
|
||||
@Override
|
||||
public boolean after(Object target, Method method, Object[] args) {
|
||||
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) {
|
||||
//继承此类后实现此方法
|
||||
|
@ -4,26 +4,27 @@ import java.lang.reflect.Method;
|
||||
|
||||
import cn.hutool.core.date.TimeInterval;
|
||||
import cn.hutool.core.lang.Console;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
|
||||
/**
|
||||
* 通过日志打印方法的执行时间的切面
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public class TimeIntervalAspect extends SimpleAspect{
|
||||
private static final long serialVersionUID = 1L;
|
||||
public class TimeIntervalAspect extends SimpleAspect {
|
||||
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 after(Object target, Method method, Object[] args) {
|
||||
Console.log("Method [{}.{}] execute spend [{}]ms", target.getClass().getName(), method.getName(), interval.intervalMs());
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ import net.sf.cglib.proxy.MethodProxy;
|
||||
* Cglib实现的动态代理切面
|
||||
*
|
||||
* @author looly
|
||||
* @author ted.L
|
||||
*
|
||||
*/
|
||||
public class CglibInterceptor implements MethodInterceptor, Serializable {
|
||||
@ -45,14 +46,17 @@ public class CglibInterceptor implements MethodInterceptor, Serializable {
|
||||
result = proxy.invokeSuper(obj, args);
|
||||
} catch (UtilException e) {
|
||||
final Throwable cause = e.getCause();
|
||||
if (e.getCause() instanceof InvocationTargetException) {
|
||||
aspect.afterException(target, method, args, ((InvocationTargetException) cause).getTargetException());
|
||||
} else {
|
||||
throw e;// 其它异常属于代理的异常,直接抛出
|
||||
if (!(e.getCause() instanceof InvocationTargetException)) {
|
||||
// 其它异常属于代理的异常,直接抛出
|
||||
throw e;
|
||||
}
|
||||
if(aspect.afterException(target, method, args, ((InvocationTargetException) cause).getTargetException())){
|
||||
throw e;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (aspect.after(target, method, args)) {
|
||||
if (aspect.after(target, method, args, result)) {
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
|
@ -13,6 +13,7 @@ import cn.hutool.core.util.ReflectUtil;
|
||||
* JDK实现的动态代理切面
|
||||
*
|
||||
* @author Looly
|
||||
* @author ted.L
|
||||
*
|
||||
*/
|
||||
public class JdkInterceptor implements InvocationHandler, Serializable{
|
||||
@ -46,14 +47,16 @@ public class JdkInterceptor implements InvocationHandler, Serializable{
|
||||
result = ReflectUtil.invoke(target, method, args);
|
||||
} catch (UtilException e) {
|
||||
final Throwable cause = e.getCause();
|
||||
if (e.getCause() instanceof InvocationTargetException) {
|
||||
aspect.afterException(target, method, args, ((InvocationTargetException) cause).getTargetException());
|
||||
} else {
|
||||
throw e;// 其它异常属于代理的异常,直接抛出
|
||||
if (!(e.getCause() instanceof InvocationTargetException)) {
|
||||
// 其它异常属于代理的异常,直接抛出
|
||||
throw e;
|
||||
}
|
||||
if(aspect.afterException(target, method, args, ((InvocationTargetException) cause).getTargetException())){
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aspect.after(target, method, args)) {
|
||||
if (aspect.after(target, method, args, result)) {
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
|
@ -14,47 +14,60 @@ import cn.hutool.aop.aspects.TimeIntervalAspect;
|
||||
*/
|
||||
public class AopTest {
|
||||
|
||||
@Test
|
||||
public void aopTest() {
|
||||
Animal cat = ProxyUtil.proxy(new Cat(), TimeIntervalAspect.class);
|
||||
String result = cat.eat();
|
||||
Assert.assertEquals("猫吃鱼", result);
|
||||
}
|
||||
@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();
|
||||
}
|
||||
|
||||
static interface Animal {
|
||||
String eat();
|
||||
}
|
||||
interface Animal {
|
||||
String eat();
|
||||
|
||||
/**
|
||||
* 有接口
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
static class Cat implements Animal {
|
||||
void seize();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String eat() {
|
||||
return "猫吃鱼";
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 有接口
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
static class Cat implements Animal {
|
||||
|
||||
/**
|
||||
* 无接口
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
static class Dog {
|
||||
public String eat() {
|
||||
return "狗吃肉";
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String eat() {
|
||||
return "猫吃鱼";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void seize() {
|
||||
System.out.println("抓了条鱼");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 无接口
|
||||
*
|
||||
* @author looly
|
||||
*
|
||||
*/
|
||||
static class Dog {
|
||||
public String eat() {
|
||||
return "狗吃肉";
|
||||
}
|
||||
|
||||
public void seize() {
|
||||
System.out.println("抓了只鸡");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user