Spring + CrudRepository 和注释上的 AspectJ 切入点

Spring + AspectJ pointcut on CrudRepository and Annotation

我有 @Tenantable 注释来决定切入点:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Tenantable {
}

这是我的方面:

 @Slf4j
    @Aspect
    @Configuration
    public class TenancyAspect {

        @Pointcut("execution(public * *(..))")
        public void publicMethod() {}

        @Around("publicMethod() && @within(com.sam.example.aspect.aspectexample.model.Tenantable)")
        public Object tenatable(ProceedingJoinPoint joinPoint) throws Throwable {
            System.out.println("my operations ...");
            return joinPoint.proceed();
        }
    }

这项服务没有任何问题 class :

@Tenantable
@Service
public class MyService(){
    public void doSomething(){
            ...
    }
}

当我调用 doSomething() 方法时,我的切面是 运行,没问题,但我想为属于 spring 数据的 CrudRepository 接口实现切面。

我改变了我的方面来实现如下所示:

@Slf4j
@Aspect
@Configuration
public class TenancyAspect {

    @Pointcut("execution(public * *(..))")
    public void publicMethod() {}


    @Pointcut("this(org.springframework.data.repository.Repository)")
    public void repositoryExec(){}


    @Around("publicMethod() && repositoryExec() && @within(com.sam.example.aspect.aspectexample.model.Tenantable)")
    public Object tenatable(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("my operations ...");
        return joinPoint.proceed();
    }
}

这是存储库:

@Tenantable
@Repository
public interface MyRepository extends CrudRepository{
}

但是当我在 MyRepository 中调用任何方法时它都不起作用。

有办法吗?

编辑: 当我应用这些时,它适用于所有存储库:

@Pointcut("execution(public * org.springframework.data.repository.Repository+.*(..))")

并排除这个:

@within(com.sam.example.aspect.aspectexample.model.Tenantable)

但是我需要这个注释来将它应用于特定的存储库。

您的 repositoryExec 切入点应以 + 结尾,以建议 Repository

的所有子类
  @Pointcut("this(org.springframework.data.repository.Repository+)")

再看一眼,我想我知道这里发生了什么:你假设只是因为你做了你的注释 @Inherited,如果你注释一个接口。但这个假设是错误的。 @Inherited 仅适用于一种情况:扩展带注释的基 class 时。它不适用于带注释的接口、方法等。这也记录在案 here:

Note that this meta-annotation type has no effect if the annotated type is used to annotate anything other than a class. Note also that this meta-annotation only causes annotations to be inherited from superclasses; annotations on implemented interfaces have no effect.

一旦您注释了您的实施 class,它就会起作用。