以下是我的代码段:
ServiceImpl.java
@Service
public class ServiceImpl implements Service {
private Response worker(Audit send) throws ArgumentException {
System.out.println("STEP_1");
worker(send.getRequest(), send.getId());
}
private Response worker(Request request, String id) throws ArgumentException {
System.out.println("STEP_2");
try {
//throwing some exception
} catch (Exception e) {
System.out.println("STEP_3");
}
}
}
现在,我想要的是从方法NullPointerException
抛出worker(Request request, String id)
,如上所示,我想执行一些特定的任务。为此,我写了一个Aspect类,其中包括:
MyAspect.java
@Aspect
@Component
public class MyAspect{
@Pointcut("com.xyz.myapp.ServiceImpl.worker() && args(request,..)")
private void someOperation(Request request) {}
@Before("someOperation(request)")
public void process(Request request) {
System.out.println("SUCCESS");
}
@AfterThrowing("com.xyz.myapp.ServiceImpl.worker() && args(request,..)")
public void doRecoveryActions() {
System.out.println("EXCEPTION_SUCCESS");
}
}
当前输出:
STEP_1
STEP_2
STEP_3
期望输出:
STEP_1
STEP_2
STEP_3
SUCCESS
EXCEPTION_SUCCESS
正如您所看到的,MyAspect.java
未被触发,因此不打印值。
这可能是什么原因?
注意:
我也尝试将工人作为公共课程,但它没有用。
还尝试更改方法的名称,以消除任何无法解决的超载问题。
截至目前,尝试各种其他切入点表达式都是徒劳的。
在我的应用程序中,还有其他方面类可以正常工作。
答案 0 :(得分:3)
你做了一个典型的Spring AOP初学者的错误:你认为它适用于私有方法,但正如文档明确指出的那样,它没有。 Spring AOP基于动态代理,当使用CGKIB代理实现接口时,它们仅适用于公共方法,还适用于受保护和包范围方法。
如果你想从一个方面拦截它,你应该公开worker()
方法。
P.S。:完全成熟的AspectJ也适用于私有方法,但是切换到另一个AOP框架在这里会有点过分。
更新:您的代码中还有其他问题:
worker
方法,即使您将其公开,也不会返回任何内容。最后一个语句应为return worker(send.getRequest(), send.getId());
,而不仅仅是worker(send.getRequest(), send.getId());
。com.xyz.myapp.ServiceImpl.worker()
永远不会匹配,因为它有一个空参数列表,但你的方法有参数。 args()
对您没有帮助。*
。此外,方法名称本身是不够的,它应该包含在实际的切入点类型中,例如execution()
。即你想写一些类似的东西:@Pointcut("execution(* com.xyz.myapp.ServiceImpl.worker(..)) && args(request, ..)")
private void someOperation(Request request) {}
答案 1 :(得分:0)
要拦截抛出异常的方法,您可以使用此代码(仅当方法是公共的时才有效):
calendarView.calendarWeekdayView.removeFromSuperview()
来源:Spring AOP