Вызов другого метода прокси из Spring Aspect

У меня два разных аспекта. Как я могу гарантировать, что при вызове метода с одного аспекта он все равно будет проходить через цепочку прокси?

Вот соответствующий код:

Внутренний аспект:

@Around("withinReplicatedRepository() && entityMethod() && insertMethod()")
public Object trackInsert(ProceedingJoinPoint jp) throws Throwable {
    return trackChange(jp, ChangeType.INSERT, jp.getArgs()[0]);
}

Внешний аспект:

@Around("withinReplicatedRepository() && entityMethod() && autoSaveRepository() && saveMethod()")
public Object saveEntity(ProceedingJoinPoint jp) throws Throwable {
    TransactionUtil.ensureTransactional();

    Object entity = jp.getArgs()[0];
    AutoSaveRepository repository = (AutoSaveRepository)jp.getTarget();
    if (repository.exists(entity)) {
        repository.update(entity);
    } else {
        repository.insert(entity);
    }
    return null;
}

Применение:

AutoSaveRepository<MyEntity> repo = ...;
repo.save(entity);

Моя проблема в том, что jp.getTarget () вернет исходный класс, поэтому repository.insert () не будет захвачен trackInsert.

Что такое ... в AutoSaveRepository<MyEntity> repo = ...;? AutoSaveRepository - это одноэлементный компонент? Тогда должно быть легко получить компонент для этого с помощью getBean(..).

kriegaex 29.03.2018 05:00

Это не синглтон, есть несколько экземпляров AutoSaveRepository.

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

Ответы 1

Ответ принят как подходящий

Можешь попробовать

AopContext.currentProxy()

См. Javadoc.

При этом необходимо, чтобы вы активировали доступ к прокси:

  • В XML вы можете сделать это, начиная с Spring 3.0.3, через
    <aop:aspectj-autoproxy expose-proxy = "true"/>.
  • В конфигурации в стиле аннотации вы можете сделать это, начиная с 4.3.1, через
    @EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true),
    см. Javadoc

Я видел это в других обсуждениях. Но разве AopContext.currentProxy() не считается чем-то вроде взломать?

Sasa 29.03.2018 09:30

Это задокументировано в Spring Javadoc. Что бы вы подумали? Но если у вас есть другой способ получить экземпляр компонента (прокси), используйте его. В качестве альтернативы используйте полный AspectJ с LTW и избавьтесь от прокси Spring.

kriegaex 29.03.2018 09:49

Это немного похоже на взлом (см. Также этот ответ: stackoverflow.com/a/7482767/353563), но если это единственный способ, то у меня нет особого выбора. В идеале в ProceedingJoinPoint должен быть метод для получения исходного объекта, но я понимаю, почему этого трудно достичь.

Sasa 03.04.2018 09:59

Итак, потому что один человек в другом ответе сказал, что это означает, что это взлом? На самом деле у Spring AOP есть свои ограничения. По сравнению с AspectJ это скорее "AOP lite", но если вы не хотите переключаться, вы должны брать то, что предлагается. :-)

kriegaex 03.04.2018 16:29

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