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,它就会起作用。
我有 @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,它就会起作用。