Spring + AspectJ pointcut в CrudRepository и Annotation

У меня есть аннотация @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)

Но мне нужна эта аннотация, чтобы применить ее к конкретным репозиториям.

Как вы можете ожидать, что это будет работать с MyService? Класс не расширяет и не реализует ничего, связанного с Reporitory. или @CrudRepository. Или вы хотите настроить таргетинг на другой класс? Если да, покажите, пожалуйста, этот класс вкл. имя пакета.

kriegaex 03.08.2018 07:11

Это всего лишь образец, который я хотел показать, он работает над конкретным классом, имеющим аннотацию @tenantable. Но для репозиториев это не работает.

sam 03.08.2018 07:51

Точно! Итак, где ваш пример того, что работает нет? Это то, что вы ищете здесь ответы, не так ли? Пожалуйста, предоставьте MCVE, вот как вы получите здесь свои ответы.

kriegaex 03.08.2018 08:03

@kriegaex Я редактировал

sam 04.08.2018 16:41

Все, что вы сделали, это добавили интерфейс MyRepository. Где находится класс, реализующий этот интерфейс, и как он используется? Что насчет MCVE ты не понимаешь? Вы вообще читали статью? Я не могу скомпилировать и запустить ваш код, так как он неполный. Вы скрываете именно те части приложения, с которыми у вас возникли проблемы. В этом нет особого смысла.

kriegaex 05.08.2018 05:38
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
5
1 418
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ваш repositoryExec pointcut должен заканчиваться на +, чтобы советовать всем подклассам Repository.

  @Pointcut("this(org.springframework.data.repository.Repository+)")

как это `@Pointcut (" this (org.springframework.data.repository.Reposito‌ ry. +) ")` ??

sam 29.07.2018 15:29

Я пробовал, но он не работает для моих методов CrudRepository.

sam 29.07.2018 15:37

можешь посмотреть мою правку? моя аннотация не работает для репозиториев

sam 29.07.2018 16:13

Вы пытаетесь посоветовать метод репозитория, но аннотация находится в сервисе?

Mạnh Quyết Nguyễn 29.07.2018 16:36

нельзя ли указать в интерфейсе или мне нужно изучить и попробовать еще? Ты знаешь?

sam 29.07.2018 22:07
Ответ принят как подходящий

Взглянув еще раз, я думаю, что знаю, что здесь происходит: вы предполагаете, что только потому, что вы сделали свою аннотацию @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.

Как только вы аннотируете свой реализующий класс, он заработает.

Другие вопросы по теме