在CrudRepository和Annotation上的Spring + AspectJ切入点 [英] Spring + AspectJ pointcut on CrudRepository and Annotation
问题描述
我有@Tenantable注释来决定pointCut:
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.
反正有这样做吗?
当我应用这些库时,它适用于所有存储库:
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屋!