CrudRepository 和 Annotation 上的 Spring + AspectJ 切入点 [英] Spring + AspectJ pointcut on CrudRepository and Annotation

查看:26
本文介绍了CrudRepository 和 Annotation 上的 Spring + AspectJ 切入点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have @Tenantable annotation to decide for 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();
        }
    }

这对于这个服务类没有任何问题:

This is working without any problem for this service class :

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

当我调用 doSomething() 方法时,我的切面正在运行,没关系,但我想为属于 spring 数据的 CrudRepository 接口实现切面.

my aspect is running when I call doSomething() method, It is ok but I want to implement aspect for CrudRepository interface that belongs spring data.

我已经改变了我的方面来实现这个,如下所示:

I have changed my Aspect to achieve this like below :

@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 中的任何方法时它不起作用.

But it doesn't work when I call any method inside of MyRepository.

有没有办法做到这一点?

Is there anyway to do this?

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

Edit : It works for all repositories when I apply these :

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

并排除这个:

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

但是我需要这个注解来将它应用到特定的仓库.

But I need this anotation to apply it for specific repositories.

推荐答案

再看一看,我想我知道这里发生了什么:你假设仅仅因为你做了注释 @Inherited,如果你注释一个接口,它将通过实现类来继承.但这个假设是错误的.@Inherited 仅适用于一种情况:扩展带注释的基类时.它不适用于带注释的接口、方法等.这也记录在 此处:

Having taken another look, I think I know what is going on here: You are assuming that just because you made your annotation @Inherited, it will be inherited by implementing classes if you annotate an interface. But this assumption is wrong. @Inherited only works in exactly one case: when extending an annotated base class. It does not work for annotated interfaces, methods etc. This is also documented 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.

只要你注释你的实现类,它就会起作用.

As soon as you annotate your implementing class, it works.

这篇关于CrudRepository 和 Annotation 上的 Spring + AspectJ 切入点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆