У меня есть аннотация @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 (). Это нормально, но я хочу реализовать аспект для интерфейса CrudRepository, который принадлежит данным Spring.
Я изменил свой аспект, чтобы добиться этого, как показано ниже:
@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)
Но мне нужна эта аннотация, чтобы применить ее к конкретным репозиториям.
Это всего лишь образец, который я хотел показать, он работает над конкретным классом, имеющим аннотацию @tenantable. Но для репозиториев это не работает.
Точно! Итак, где ваш пример того, что работает нет? Это то, что вы ищете здесь ответы, не так ли? Пожалуйста, предоставьте MCVE, вот как вы получите здесь свои ответы.
@kriegaex Я редактировал
Все, что вы сделали, это добавили интерфейс MyRepository. Где находится класс, реализующий этот интерфейс, и как он используется? Что насчет MCVE ты не понимаешь? Вы вообще читали статью? Я не могу скомпилировать и запустить ваш код, так как он неполный. Вы скрываете именно те части приложения, с которыми у вас возникли проблемы. В этом нет особого смысла.




Ваш repositoryExec pointcut должен заканчиваться на +, чтобы советовать всем подклассам Repository.
@Pointcut("this(org.springframework.data.repository.Repository+)")
как это `@Pointcut (" this (org.springframework.data.repository.Reposito ry. +) ")` ??
Я пробовал, но он не работает для моих методов CrudRepository.
можешь посмотреть мою правку? моя аннотация не работает для репозиториев
Вы пытаетесь посоветовать метод репозитория, но аннотация находится в сервисе?
нельзя ли указать в интерфейсе или мне нужно изучить и попробовать еще? Ты знаешь?
Взглянув еще раз, я думаю, что знаю, что здесь происходит: вы предполагаете, что только потому, что вы сделали свою аннотацию @Inherited, она будет унаследована путем реализации классов, если вы аннотируете интерфейс. Но это предположение неверно. @Inherited работает только в одном случае: при расширении аннотированного базового класса. Это не работает для аннотированных интерфейсов, методов и т. д. Это также задокументировано здесь:
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.
Как только вы аннотируете свой реализующий класс, он заработает.
Как вы можете ожидать, что это будет работать с
MyService? Класс не расширяет и не реализует ничего, связанного сReporitory. или@CrudRepository. Или вы хотите настроить таргетинг на другой класс? Если да, покажите, пожалуйста, этот класс вкл. имя пакета.