[英]Spring + AspectJ pointcut on CrudRepository and Annotation
I have @Tenantable annotation to decide for pointCut :我有 @Tenantable 注释来决定 pointCut :
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Tenantable {
}
this my aspect :这是我的方面:
@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(){
...
}
}
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.当我调用 doSomething() 方法时,我的方面正在运行,没关系,但我想为属于 spring 数据的 CrudRepository 接口实现方面。
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();
}
}
this is repository :这是存储库:
@Tenantable
@Repository
public interface MyRepository extends CrudRepository{
}
But it doesn't work when I call any method inside of MyRepository.但是当我调用 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+.*(..))")
and exclude this :并排除这个:
@within(com.sam.example.aspect.aspectexample.model.Tenantable)
But I need this anotation to apply it for specific repositories.但是我需要这个注释才能将它应用于特定的存储库。
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.再看一眼,我想我知道这里发生了什么:你假设仅仅因为你做了你的注释@Inherited
,如果你注释一个接口,它将通过实现类来继承。 But this assumption is wrong.但这个假设是错误的。 @Inherited
only works in exactly one case: when extending an annotated base class. @Inherited
仅适用于一种情况:扩展带注释的基类时。 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.只要您注释您的实现类,它就会起作用。
您的repositoryExec
切入点应以+
结尾,以建议Repository
所有子类
@Pointcut("this(org.springframework.data.repository.Repository+)")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.