Java 为什么Spring-Around通知可以通过目标方法吞并或停止异常thown的传播?
我正在学习Spring Core认证,根据我的学习材料,我对这个问题有以下疑问: 关于通知类型和类型,以下哪项陈述是不正确的 异常处理Java 为什么Spring-Around通知可以通过目标方法吞并或停止异常thown的传播?,java,spring,spring-mvc,aop,spring-aop,Java,Spring,Spring Mvc,Aop,Spring Aop,我正在学习Spring Core认证,根据我的学习材料,我对这个问题有以下疑问: 关于通知类型和类型,以下哪项陈述是不正确的 异常处理 如果之前的通知引发异常,则不会调用目标方法 Around通知可以通过目标方法吞并或停止异常的传播 返回后的通知类型可以通过目标方法吞并或停止异常的传播 现在我知道上一个问题的正确答案是最后一个(我有答案),但为什么 所以它问我什么陈述是不正确的,这意味着前两个陈述是正确的 我试图通过一些具体的例子来分析前3个案例,但我并不认为我的推理是正确的 1) 在建议之
- 如果之前的通知引发异常,则不会调用目标方法
- Around通知可以通过目标方法吞并或停止异常的传播
- 返回后的通知类型可以通过目标方法吞并或停止异常的传播
@Aspect
public class PropertyChangeTracker {
private Logger logger = Logger.getLogger(getClass());
@Before(“execution(void check*(*))”)
public void trackCheck() {
logger.info(“Property about to check…”);
}
}
因此,每次执行checkSomething(oneArgument)方法时,都会执行已实现的建议(将日志行创建到.log文件中)。如果在执行此方法期间引发异常,则不会执行通知
我认为这是相当清楚的
2) 环绕建议,我知道这是环绕建议的序列图
我有以下这类建议的例子:
@Around("execution(* com.journaldev.spring.model.Employee.getName())")
public Object employeeAroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
System.out.println("Before invoking getName() method");
Object value = null;
try {
value = proceedingJoinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
System.out.println("After invoking getName() method. Return value="+value);
return value;
}
阅读官方文件后,我发现:
环绕建议:环绕连接点(如方法)的建议
调用。这是最有力的建议。围绕建议
可以在方法调用前后执行自定义行为。信息技术
还负责选择是否继续到连接点
或者通过返回其自己的方法来缩短建议方法的执行
返回值或引发异常
因此,在我看来,Around advice用于在jointpoint执行之前和之后剪切方法执行。我们可以使用它来控制建议的方法是否执行。我们还可以检查返回值并对其进行更改。这是最有力的建议,需要正确应用
因此,在前面的示例中,我认为它执行了两次:第一次是在执行getName()方法之前,第二次是在执行getName()方法之后
但是,究竟是什么呢
value = proceedingJoinPoint.proceed();
我认为这是连接点前后执行的分界点,在这种情况下,我认为procedure()方法表示必须执行getName()方法,其结果将被放入value字段。这是对的还是我遗漏了什么
回到原来的立场,我可以这么说
一个周围的建议可以吞咽或阻止病毒的传播
目标方法引发的异常
为什么我能说这是真的?具体的意思是什么?使用
@Around
就像编写自己的代码并调用一个方法,只是使用了proceedingJoinPoint.procedure()
。与普通方法调用一样,您可以选择不执行它(在条件中包装它)或捕获它抛出的错误(在try块中包装调用)
从:
Around通知是使用@Around注释声明的。advice方法的第一个参数必须是ProceedingJoinPoint类型。在通知体中,对ProceedingJoinPoint调用continue()会导致底层方法执行。也可以通过传入对象[]来调用procedure方法-数组中的值将在方法执行时用作参数
因此,具体来说:value=proceedingJoinPoint.procedure()
导致调用底层方法,并将其返回值指定给值
Around通知可以通过目标方法吞并或停止异常的传播
这是通过以下方式实现的:
try {
proceedingJoinPoint.proceed();
} catch (Throwable e) {
// ignore or handle
}
因此,在前面的示例中,我认为它执行了两次:执行getName()方法之前的第一次,执行getName()方法之后的第二次
如果我理解你的想法,你就错了。通知只被调用一次,其中的代码负责调用实际的通知方法getName()
。这就是proceedingJoinPoint.procedure()
所做的
一个典型的场景是:拦截方法调用,执行一些检查,调用方法(或者不调用,可能取决于检查的结果),然后返回结果。在您发布的示例中,
procedure()
被try-catch
块包围,这意味着您可以捕获由getName()
引发的异常并对其执行任何操作。这就解释了为什么你问题中的第二句是正确的。那么(与我的原始示例相关)你的意思是当我处理JoinPoint.Procedure()时会执行employeeAroundAdvice()方法,如果它抛出异常,我可以捕获它并处理或忽略它吗?当你调用Procedure()
时,Employee.getName()调用了
方法,如果您将此调用包装在一个try catch中,您可以处理或忽略它,是的。@beerbajay如果Employee.getName()
正在捕获异常,我在Employee.getName()
的catch块中有某种恢复机制,我们有关于继续()的建议
使用try-catch..首先在哪里捕获?我的恢复机制会在insi中执行吗