这是我第一次接触AOP。我有一个带有一个方面的弹簧启动应用程序,一个记录器。搜索我得出的结论是,@Around方法在该方法之前和之后执行(我只在一种方法中调用它(,这是对的吗? 在我的@Around方法中间,y有一个joinPoint.proceed()
.如果我没记错的话,JoinPoint
是我必须用来获取调用该方面的方法信息的对象,但我无法理解实际在做什么!
这是我的代码:
@Around(value = "execution(* *(..)) && @annotation(Loggable)", argNames = "ProceedingJoinPoint, Loggable")
public Object logAround(ProceedingJoinPoint joinPoint, Loggable loggable) throws Throwable {
String methodArguments = loggable.printMethodArguments() ? Arrays.toString(joinPoint.getArgs()) : "[]";
long start = System.currentTimeMillis();
Object returnObject = joinPoint.proceed(); // continue on the
// intercepted method
long elapsedTime = System.currentTimeMillis() - start;
String returnValue = loggable.printReturn() && returnObject != null ? returnObject.toString() : "[]";
LOG.info("Logging method: {}.{} Method arguments: {}. Method return value: {}. Method execution time: {}",
joinPoint.getTarget().getClass().getName(), joinPoint.getSignature().getName(), methodArguments,
returnValue, elapsedTime);
return returnObject;
}
正如你所说,当你使用@Around
就像你可以在方法之前做任何你想做的事情,然后调用该方法,然后你可以在调用方法之后做任何你想做的事情。
//Read file, Log , .... (Before method calling)
//Invoke the method (joinPoint.proceed)
//Write to the file, complete log, .... (After method calling)
joinPoint.proceed()
完成的调用阶段。
日志示例
1-调用方法前的日志
2-调用或调用您在其上设置的切入点的方法(proceed
(
3-将日志保存到数据库中或将其写入文件或将其发送到,...
授权示例
在此示例中,使用@Around
,您可以授权用户并确定他们是否可以使用该方法?
所以你需要在方法调用之前做授权过程,如果授权true
则调用方法,如果没有抛出异常,或者你可以记录。
1-在调用方法之前授权用户
2-如果true
授权,则调用方法(joinPoint.proceed();
(
总之,joinPoint.proceed();
意味着您正在调用或调用 set 方法。
正如你提到的,@Around
建议围绕着一个连接点,例如方法调用。它可以在方法调用之前和之后执行自定义行为。它还负责选择是继续到连接点还是缩短建议的方法执行。
在您的情况下,实际的方法调用(那些包含非常有用的业务逻辑的方法!(是由于joinPoint.proceed();
而发生的。
@Around("someMethod()")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("around - before - " + joinPoint.getSignature());
try {
System.out.println("Inside Try block of around");
return joinPoint.proceed();
} finally {
System.out.println("around - after - " + joinPoint.getSignature());
}
}
@Before("someMethod()")
public void before(JoinPoint joinPoint) {
System.out.println("before - " + joinPoint.getSignature());
}
/*Consider above methods are matched to a pointcut for some joinpoint. If we didn't
use joinPoint.proceed() in @Around advice then @Before advice will not be called.
Output with joinPoint.proceed()
-around - before - " + joinPoint.getSignature()
-"Inside Try block of around";
-"before - " + joinPoint.getSignature()
-around - after - " + joinPoint.getSignature()
Output without joinPoint.proceed()
-around - before - " + joinPoint.getSignature()
-"Inside Try block of around";
-around - after - " + joinPoint.getSignature()
*/