我正在与:
Spring Framework
4.3.3AspectJ
1.8.9
我有以下正常过程:
@Controller
->@Service
->@Repository
我有以下一对AOP
:
PersonaServicePointcut
PersonaServiceAspect
场景如下:
该类有一些方法,@Service
例如: delete
、和。它们在同一个类中一起声明。save
update
findOneById
对于诸如delete
和update
通过之类的方法,AOP
我使用一个@Before
或@Around
建议来调用该findOneById
方法。
原因是如果实体不存在,执行delete
or方法(考虑 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
@Around
findOneById
logging
audit
@ControllerAdvice
问题是当其他方法的建议被delete/update/save
执行时(记住他们也调用并执行了findOneById
方法)我findOneByIdPointcut
被不必要地执行了。
我需要更改切入点声明以指示如下内容:
@Pointcut(Alpha)
public void findOneByIdPointcut(String id){}
在哪里Alpha
:
执行@Service
'sfindOneById
方法的 before/around 建议,但 如果它的调用是从类的其他建议中完成的,则永远不会
PersonaServiceAspect
。
我尝试了很多方法!execution
和!within
组合,但没有结果。
即使我只创建了一个切入点,它使用其各自独特的建议拦截 所有's 方法,并且通过参数我能够检查调用了什么方法,然后执行相应的控制。但是这种行为再次发生。@Service
@Around
ProceedingJoinPoint proceedingJoinPoint
这意味着,通过以下方式:
@Around("PersonaServicePointcut.anyMethodPointcut()")
public Object aroundAdviceAnyMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
anyMethodPointcut
在哪里execution(* mypackage.PersonaServiceImpl.*(..))
有可能实现这种方法吗?如何?
谢谢。