【发布时间】:2020-10-31 17:19:39
【问题描述】:
我有一个这样的 Spring-Data 存储库:
package com.example.demo;
@RepositoryRestResource
public interface FooRepository extends JpaRepository<Foo, Long> {
@Override
<S extends Foo> S save(S entity);
@Override
<S extends Foo> List<S> saveAll(Iterable<S> entities);
}
还有这样的一个方面:
@Aspect
@Component
public class FooAspect {
@Before("execution(* org.springframework.data.repository.CrudRepository.save(*))")
void crudSaveBefore(JoinPoint joinPoint) throws Throwable {
System.out.println("crud save");
}
@Before("execution(* com.example.demo.FooRepository.save(*))")
void fooSaveBefore(JoinPoint joinPoint) throws Throwable {
System.out.println("foo save");
}
@Before("execution(* org.springframework.data.repository.CrudRepository.saveAll(*))")
void crudSaveAll(JoinPoint joinPoint) throws Throwable {
System.out.println("crud save all");
}
@Before("execution(* com.example.demo.FooRepository.saveAll(*))")
void fooSaveAll(JoinPoint joinPoint) throws Throwable {
System.out.println("foo save all");
}
}
当我运行 fooRepository.save(..) 时,在控制台中我看到:foo save
当我运行fooRepository.saveAll(..) 时,我在控制台中看到foo save all 和crud save all
我期待 saveAll 只拦截 FooRepository 风格,因为我直接切入 package.class.method。这似乎适用于save,但不适用于saveAll。
这是因为saveAll 中的参数是Iterable 吗?还是泛型在这里发生某种类型的擦除?还有什么?
【问题讨论】:
-
如果我知道如何运行此代码,我很确定我可以为您提供帮助。请提供MCVE,最好在 GitHub 上。那我来看看。 (我是 Spring 菜鸟,但有点像 AOP 专家。)
-
显然您可以将切入点表达式与逻辑运算符 AND、NOT、OR 结合使用。这样,您可以使 @Before 注释中的表达式更严格,例如“匹配 FooRepo.saveAll 但不匹配 CrudRepo.saveAll”。请参阅此处的“组合切入点表达式”:baeldung.com/spring-aop-pointcut-tutorial
标签: java spring-boot aop spring-aop pointcut