Можно ли создать JAR с аспектом, который автоматически применяется к классам в клиентском проекте?

Я хочу иметь JAR с аспектом, который перехватывает все вызовы методов, например.

@Aspect
public class CoolAspect {
    @Pointcut("execution(public * *(..))")
    public void anyPublicMethod() { }

    @Before("anyPublicMethod()")
    public void advice(JoinPoint point) {
       System.out.println("sign:\t" + point.getSignature());
    }
}

Предположим, что вышеизложенный аспект — это то, что у меня есть, и я хочу, чтобы клиенты использовали его. Я компилирую его в JAR и делаю доступным для Maven.

Теперь клиенты будут использовать эту банку как зависимость, например.

    <dependency>
        <groupId>cool-group</groupId>
        <artifactId>cool-artifact</artifactId>
        <version>1.0.0</version>
    </dependency>

Этот артефакт (JAR) имеет указанный аспект.

Теперь возможно ли, чтобы аспект работал просто объявив зависимость Maven?

Несколько вещей, которые могут быть важны:

  1. Я планирую использовать AspectJ (возможно, Spring AOP, если необходимо),
  2. Клиенты, вероятно, будут веб-приложениями с обычными web.xml и т. д.
  3. Клиенты создаются с помощью Maven
  4. Я хочу, чтобы клиенты были максимально просты в настройке - в моей первоначальной идее было бы достаточно зависимости от Maven.
  5. «Аннотационный JAR» будет содержать веб-фрагмент, поэтому там можно объявить некоторые пользовательские ServletContextListener.

Любые идеи?


person Parobay    schedule 19.12.2013    source источник


Ответы (2)


Найдите простое решение для этого вопроса, если вы используете spring-boot:

В банке вы можете определить свой аспект как компонент:

package com.xxx.yy.zz.aspect;
@Aspect
@Component
public class CoolAspect {
   // code like the question
}

И вам нужно создать файл spring.factories в /resources/META-INF/. Spring будет сканировать этот файл при запуске.

И файл spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.xxx.yy.zz.aspect.CoolAspect

После этого просто упакуйте их как банку.

Это будет работать, просто объявив зависимость Maven

person Chao Jiang    schedule 06.11.2019
comment
Это мне очень помогло, я создал библиотеку с некоторыми аспектами и другими утилитами, и она не работала, пока я не применил это. - person Abiyain Fadez; 21.07.2020
comment
Вы спасли меня! Я сделал именно так и это сработало! отлично - person Passella; 10.07.2021

Нет, это невозможно, потому что AspectJ должен запускаться до любых клиентских классов. Все клиентские классы должны быть загружены через специальный расширенный загрузчик классов, который будет обрабатывать аннотации.

Другое дело — АОП Spring. он создает bean-компоненты во время запуска контекста приложения и не требует специального загрузчика классов. Это был бы самый простой способ для клиента, если бы он использовал Spring. Добавьте зависимость maven, а затем настройте AOP в контексте приложения.

Существует четыре типа переплетения:

  • Плетение во время компиляции — самый простой подход. Когда у вас есть исходный код приложения, ajc скомпилирует исходный код и создаст на выходе файлы тканых классов. Вызов ткача является неотъемлемой частью процесса компиляции ajc. Сами аспекты могут быть в исходной или бинарной форме. Если аспекты необходимы для компиляции затронутых классов, то вы должны выполнить плетение во время компиляции. Аспекты необходимы, например, когда они добавляют члены в класс, а другие компилируемые классы ссылаются на добавленные члены.
  • Сплетение после компиляции (также иногда называемое бинарным сплетением) используется для объединения существующих файлов классов и файлов JAR. Как и при сплетении во время компиляции, аспекты, используемые для сплетения, могут быть в исходном или бинарном виде и сами могут быть сплетены аспектами.
  • Сплетение во время загрузки (LTW) — это просто бинарное сплетение, отложенное до момента, когда загрузчик классов загружает файл класса и определяет класс для JVM. Для поддержки этого требуется один или несколько «загрузчиков классов переплетения», которые либо предоставляются явно средой выполнения, либо активируются через «агент переплетения».
  • Плетение во время выполнения, это то, что на самом деле делает Spring. Мы определяем это как переплетение уже определенных классов. к JVM
person Mikhail    schedule 19.12.2013
comment
Хорошо, спасибо. Приятно знать, что по крайней мере Spring дает возможность для этого работать. Но есть ли у вас идея/фрагмент о том, как настроить Spring в банке аспектов? - person Parobay; 19.12.2013
comment
docs.spring.io/spring/docs/2.5.4/ reference/aop.html — здесь есть документация. Вы упаковываете аспекты в банку, затем клиент добавляет зависимость maven и вставляет их в контекст приложения. - person Mikhail; 19.12.2013
comment
Смотрите, в чем дело. Я не хочу, чтобы клиент вставлял их в контекст приложения. Тогда это банально. У клиентов также может не быть контекста приложения, потому что они не используют Spring. Этот аспект должен работать для обычных классов, например. сервлеты, зарегистрированные в клиенте web.xml - person Parobay; 19.12.2013
comment
Боюсь, просто добавив зависимость от maven, этого невозможно добиться. Вы должны выбрать наименьшее зло. ;) - person Mikhail; 19.12.2013