我正在攻读Spring Core认证,对于基于我的学习材料的这个问题,我有以下疑问:
以下哪些建议类型和建议不符合 异常处理?
如果之前建议引发异常,则不会调用目标方法。
围绕建议可以吞下或停止目标方法所引发的异常的传播。
AfterReturning 建议类型可以吞噬或停止目标方法所引发的异常的传播。
现在我知道上一个问题的正确答案是最后一个(我有答案),但为什么?
所以它问我什么样的陈述不正确所以这意味着前两个陈述是真的。
我试图分析之前的3个案例做一些具体的例子,但我并不认为我的推理是正确的。
1)建议之前:
我可以这样:
@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 ADVICE ,我知道这是周围建议
的序列图
我有以下这种建议的例子:
@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;
}
阅读我发现的官方文档:
围绕建议:围绕连接点(例如方法)的建议 调用。这是最有力的建议。围绕建议 可以在方法调用之前和之后执行自定义行为。它 还负责选择是否继续加入点 或者通过返回自己的方法来快速建议的方法执行 返回值或抛出异常。
所以在我看来,周围建议用于在联合点执行之前和之后切断方法执行。我们可以用它来控制建议的方法是否会执行。我们还可以检查返回的值并进行更改。这是最有力的建议,需要正确应用。
所以在上一个例子中,我认为它执行了两次:第一个执行 getName()方法之前,第二个执行 getName()< / strong>方法已执行。
但
究竟是什么呢?value = proceedingJoinPoint.proceed();
我认为它是联合点之前和之后的执行之间的分界点,在这种情况下我认为 proceed()方法说 getName()必须执行strong>方法,并将其结果放入值字段。是对的还是我错过了什么?
所以回到原来的陈述我可以说
围绕建议可以吞下或停止传播 目标方法所引发的异常。
为什么我能说这是真的?什么是繁琐的意思?
答案 0 :(得分:6)
所以在前面的例子中我认为它执行了两次:第一个执行getName()方法之前执行,第二个执行getName()方法之后执行。
如果我理解你的想法,那你错了。该建议只被调用一次,其中的代码负责调用实际的建议方法getName()
。这就是proceedingJoinPoint.proceed()
所做的。
一个典型的场景 - 你拦截方法调用,执行一些检查,调用方法(或不,可能取决于检查的结果),并返回结果。在您发布的示例中,proceed()
被try - catch
块包围,这意味着您可以捕获getName()
抛出的异常并随意执行任何操作。这就解释了为什么你问题中的第二句是真的。
答案 1 :(得分:5)
使用@Around
就像编写自己的代码并调用方法一样,除了您使用proceedingJoinPoint.proceed()
之外。与普通方法调用一样,您可以选择不执行它(将其包装在条件中)或捕获它抛出的错误(将调用包装在try块中)。
使用@Around注释声明around建议。 advice方法的第一个参数必须是ProceedingJoinPoint类型。在通知的主体内,在ProceedingJoinPoint上调用proceed()会导致执行基础方法。 proceed方法也可以被称为传入Object [] - 数组中的值将在进行时用作方法执行的参数。
因此,具体来说:value = proceedingJoinPoint.proceed();
会导致调用基础方法,并将其返回值分配给value
。
周围的建议可以吞噬或停止目标方法所引发的异常的传播。
这可以通过以下方式实现:
try {
proceedingJoinPoint.proceed();
} catch (Exception e) {
// ignore or handle
}