我正在与:
Spring Framework4.3.3AspectJ1.8.9
我有以下正常过程:
@Controller->@Service->@Repository
我有以下一对AOP:
PersonaServicePointcutPersonaServiceAspect
场景如下:
该类有一些方法,@Service例如: delete、和。它们在同一个类中一起声明。saveupdatefindOneById
对于诸如delete和update通过之类的方法,AOP我使用一个@Before或@Around建议来调用该findOneById方法。
原因是如果实体不存在,执行deleteor方法(考虑 Rest 场景)是没有意义的。update因此,advice必须抛出异常,比如说 Exception A,它必须在@ControllerAdvice
该方法实际上采用了相同的save方法。因此,在执行save方法之前,其他 @Before或@Around通知再次调用该findOneById方法。如果实体已经存在,则必须抛出异常,比如说 Exception B,它必须在@ControllerAdvice
请注意,我有 3 个点/3 个使用该findOneById方法的建议。它检查是否存在实体。
例如:
@Pointcut(value=
"execution(* mypackage.PersonaServiceImpl.saveOne(otherpackage.Persona))
&& args(persona)")
public void saveOnePointcut(Persona persona){}
@Pointcut(value=
"execution(*
mypackage.PersonaServiceImpl.updateOne(otherpackage.Persona))
&& args(persona)")
public void updateOnePointcut(Persona persona){}
@Pointcut(value="execution(*
mypackage.PersonaServiceImpl.deleteOne(String)) && args(id)")
public void deleteOnePointcut(String id){}
同样:这 3 个建议使用或执行该findOneById方法。
问题是当我添加一个新的切入点时,例如:
@Pointcut(value="execution(*
mypackage.PersonaServiceImpl.findOneById(String))
&& args(id)")
public void findOneByIdPointcut(String id){}
我创建了这个切入点来检查一个实体是否已经存在,如果它不存在,它必须抛出一个类型的异常C(它适用于经典的 404)。
通过对方法本身的or建议执行该findOneById方法似乎是多余的。但我需要这个来达到目的,也需要创建C类型的例外。它必须由某些人处理@Before@AroundfindOneByIdloggingaudit@ControllerAdvice
问题是当其他方法的建议被delete/update/save执行时(记住他们也调用并执行了findOneById方法)我findOneByIdPointcut被不必要地执行了。
我需要更改切入点声明以指示如下内容:
@Pointcut(Alpha)
public void findOneByIdPointcut(String id){}
在哪里Alpha:
执行@Service'sfindOneById方法的 before/around 建议,但 如果它的调用是从类的其他建议中完成的,则永远不会
PersonaServiceAspect。
我尝试了很多方法!execution和!within组合,但没有结果。
即使我只创建了一个切入点,它使用其各自独特的建议拦截 所有's 方法,并且通过参数我能够检查调用了什么方法,然后执行相应的控制。但是这种行为再次发生。@Service@AroundProceedingJoinPoint proceedingJoinPoint
这意味着,通过以下方式:
@Around("PersonaServicePointcut.anyMethodPointcut()")
public Object aroundAdviceAnyMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
anyMethodPointcut在哪里execution(* mypackage.PersonaServiceImpl.*(..))
有可能实现这种方法吗?如何?
谢谢。