背景
我使用AOP通过拦截Spring数据存储库的保存和删除方法来创建/删除受管实体的Spring ACL记录。我的所有存储库都是带有注释的接口,扩展了分页和排序存储库或粗存储库。这在过去一直很有效。不幸的是,我无法准确确定它停止工作的时间点(或代码更改)。
预期行为
以下建议适用于所有保存方法。
@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();
}
注意:我尝试了各种组合的启用代理(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();
}
同样的故事-注释在一个存储库中工作,但对于执行(…save…)的存储库不会启动 切入点失败。
出于测试目的,我通过将一个空实体从Postman发布到每个相应的存储库Restendpoint来调用这两种方法。但是,当直接从我的代码调用存储库时,也会发生同样的问题。
为了完整起见,存储库代码(即使使用最基本的repo实现也会出现不一致的行为):
编辑:我将存储库简化到最低限度---
@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方面?Spring如何填充调用拦截器链?
解决AOP问题的最佳方法是什么?(假设执行和注释切入点都失败)
稍有不同的是——使用JPA审计进行ACL管理而不是AOP是否可取?
版本
Spring 5.0.8。RELEASE,Spring数据rest 3.0.9。释放,Spring数据jpa 2.0.9。释放(均由Spring Boot 2.0.4管理)
该问题似乎是由Spring Booot的@Enable...
注释和我的@Configuration
类的不幸组合引起的。该框架似乎有几种不同的方法来确定类/接口代理(源于@EnableCache
、@EnableTransactionManagement
、@EnableAeyJAutoProxy
、@EnableAsync
)。在某些情况下,它们似乎劫持了预期的行为。我能够通过以下方式恢复预期的行为:
我无法确定哪个组合导致了不一致的行为,即我没有最小的可复制测试用例。
对于不一致的MethodInvocationInterceptor链背后的根本原因,我仍感兴趣。
嗨,我有一个使用Spring 5、Spring Data、Spring AOP和Java 11的应用程序(我也在使用JAVA 9模块系统)。我的spring-context/spring-aspects版本是5.1.2.RELEASE Spring数据版本是2.1.2.RELEASE这两个版本都是最新的。我以下列方式创建了存储库: 我已启用Spring Data Repositories使用 在我
我试图创建一些切入点和之前的建议为存储库,以便能够在Spring启动的Spring数据中过滤一些存储库的实体管理器。我在项目中也有Web和服务层,AounLogging适用于两者。但是我不能为存储库做同样的事情。我已经挣扎了2天,我尝试了很多东西来修复它。我几乎阅读了关于此的每个文档、问题和线程(代理问题CGlib和JDK代理等)。我使用jhipster创建项目。 除了@Pointcut和Crud
我需要使用spring@Cacheable注释缓存对MongoDB的调用: 不幸的是,使用@Cacheable注释接口中的任何方法都会导致以下异常: 我正在寻找一种方法来缓存对DB的调用(这相当昂贵)。有什么想法吗?
这根本不是关于Spring靴的。 我的英语可以更好。 使用下面的Spring Data配置,我正在尝试执行DML请求。 恰好是< code>CrudRepository#save方法。 然而,执行Spring的CrudRepository#保存方法,我接下来要做的是: 只有选择由功能记录。 没有执行任何“插入”或“更新”语句来hibernate.show_sql日志记录。 数据库根本没有变化。 =
我想知道是否有任何机制可以在Spring Data MongoDB存储库中使用带有注释的?我希望能收到我所拥有的文件数量,而不必获取所有文件。 基本上,这在Java中相当于:
问题内容: 我已经遇到过几次这个问题,我想知道其他人在做什么。 当我创建数据库时,有时我必须每天定期将数据导入表中。我通常要做的是删除所有记录,然后从外部数据源重新导入每条记录。 很多时候,我将不得不存储更多与导入记录相关的数据,但这些数据并非来自原始导入源。通常,此“额外数据”来自用户输入。因此,我将创建另一个表,该表的主键与获取导入数据的表的键相匹配,并将此附加数据存储在新表中。如果这没有意义