上下文
我使用AOP通过拦截Spring数据存储库的save和delete方法来创建/删除托管实体的springacl记录。我所有的存储库都是
@RepositoryRestResource
带注释的接口扩展
PagingAndSortingRepository
或
CrudRepository
. 这在过去一直很有效。不幸的是,我无法确定它停止工作的时间点(或代码更改)。
预期行为
以下建议应针对所有保存方法激发。
@Pointcut("execution(* org.springframework.data.repository.*.save(*))")
public void defaultRepoSave() {}
// may be useful for overridden methods
@Pointcut("execution(* com.xxx.yyy.repository.*.save(..))")
public static void customRepoSave() {}
@Pointcut("defaultRepoSave() || customRepoSave()")
public static void repoSave() {}
@Around(value="repoSave() && args(entity)", argNames="entity")
public Object aroundSave(ProceedingJoinPoint pjp, Object entity) throws Throwable{
log.info("Saving ...");
return pjp.proceed();
}
注:我试过各种组合
@EnableAspectJAutoProxy(exposeProxy=true/false, proxyTargetClass=true/false)
问题
这些建议针对某些存储库,而不是其他存储库。两个存储库在同一个包中。调试表明这两个存储库都是代理的,但是对左边的存储库的执行完全缺少与通知相关的拦截器。右边的那个按预期进行。
为了消除切入点不匹配的可能性,我创建了一个自定义注释,并将其添加到两个存储库中的.save()方法中。
注释:
@Retention(RUNTIME)
@Target(METHOD)
public @interface AclManaged {}
用作:
@Override
@AclManaged
Entity1 save(Entity1 entity);
建议是:
@Around("@annotation(aclManaged)")
public Object aclManaged(ProceedingJoinPoint joinPoint, AclManaged aclManaged) throws Throwable {
log.info("Acl managed");
return joinPoint.proceed();
}
相同的故事-注释可以在一个存储库中工作,但是对于存储库,如果
execution(..save..)
出于测试目的,我通过从Postman向每个存储库rest端点发布一个空实体来调用这两个方法。但是,当直接从我的代码调用存储库时,也会发生同样的问题。
---编辑:我将存储库简化到最低限度---
@RepositoryRestResource(collectionResourceRel = "entity1s", path = "entity1s")
public interface Entity1Repository extends PagingAndSortingRepository<Entity1, Long> {
// this is the method that is supposed to fire two distinct advices
@Override
@AclManaged
Entity1 save(Entity1 entity);
}
@RepositoryRestResource(collectionResourceRel = "entity2s", path = "entity2s")
public interface Entity2Repository extends PagingAndSortingRepository<Entity2, Long> {
// both aspects match perfectly
@Override
@AclManaged
Entity2 save(Entity2 ics);
}
问题
解决AOP方面问题的最佳方法是什么?(如果执行和注释切入点都失败)
版本
spring5.0.8.RELEASE,springdatarest3.0.9.RELEASE,springdatajpa2.0.9.RELEASE(全部由springboot2.0.4管理)