在CrudRepository和Annotation上的Spring + AspectJ切入点

时间:2018-07-29 13:21:43

标签: java spring spring-boot aop aspectj

我有@Tenantable注释来决定pointCut:

@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();
        }
    }

对于此服务类,此方法没有任何问题:

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

当我调用doSomething()方法时,我的方面正在运行,可以,但是我想为属于spring数据的CrudRepository接口实现方面。

我已经更改了Aspect以实现以下目标:

@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)

但是我需要此注释才能将其应用于特定的存储库。

2 个答案:

答案 0 :(得分:0)

您的repositoryExec切入点应以+结尾,以建议Repository的所有子类

  @Pointcut("this(org.springframework.data.repository.Repository+)")

答案 1 :(得分:0)

再看一遍,我想我知道这是怎么回事:您假设仅仅是因为您进行了注释@Inherited,所以如果您对接口进行注释,则实现类将继承它。但是这个假设是错误的。 @Inherited仅在以下一种情况下有效:扩展带注释的基类时。它不适用于带注释的接口,方法等。这也记录在here中:

  

请注意,如果注释类型用于注释除类之外的任何内容,则此元注释类型无效。还要注意,此元注释仅使注释从超类继承;已实现的接口上的注释无效。

注释实现类后,它就会起作用。