Рубрики
Без рубрики

Сравнение Spring AOP и AspectJ

См.Преимущества и недостатки Spring AOP и AspectJ.

Автор оригинала: baeldung.

1. введение

Сегодня существует множество доступных библиотек AOP, и они должны быть в состоянии ответить на ряд вопросов:

  • Совместим ли он с моим существующим или новым приложением?
  • Где я могу реализовать AOP?
  • Как быстро он интегрируется с моим приложением?
  • Каковы накладные расходы на производительность?

В этой статье мы рассмотрим ответы на эти вопросы и представим Spring AOP и AspectJ – две самые популярные платформы AOP для Java.

2. Концепции АОП

Прежде чем мы начнем, давайте проведем быстрый обзор терминов и основных концепций на высоком уровне:

  • Аспект – стандартный код/функция, которая разбросана по нескольким местам приложения и обычно отличается от реальной бизнес-логики (например, управление транзакциями). Каждый аспект фокусируется на конкретной сквозной функциональности
  • Точка соединения – это определенная точка во время выполнения таких программ, как выполнение метода, вызов конструктора или назначение поля
  • Совет – действие, предпринятое аспектом в конкретной точке соединения
  • Pointcut – регулярное выражение, соответствующее точке соединения. Каждый раз, когда любая точка соединения совпадает с точечным разрезом, выполняется указанный совет, связанный с этим точечным разрезом
  • Плетение – процесс связывания аспектов с целевыми объектами для создания целевого объекта

3. Пружина AOP и AspectJ

Теперь давайте обсудим Spring AOP и AspectJ по нескольким осям, таким как возможности, цели, плетение, внутренняя структура, точки соединения и простота.

3.1. Возможности и цели

Проще говоря, Spring AOP и AspectJ имеют разные цели.

Spring AOP стремится обеспечить простую реализацию AOP в Spring IoC для решения наиболее распространенных проблем, с которыми сталкиваются программисты. Он не предназначен для полного решения AOP – он может быть применен только к бобам, управляемым контейнером Spring.

С другой стороны, AspectJ-это оригинальная технология AOP, которая направлена на обеспечение полного решения AOP. Он более надежен, но также значительно сложнее, чем пружинный АОП. Также стоит отметить, что AspectJ может применяться ко всем объектам домена.

3.2. Плетение

Как AspectJ, так и Spring AOP используют разные типы плетения, что влияет на их поведение в отношении производительности и простоты использования.

AspectJ использует три различных типа плетения:

  1. Ткачество во время компиляции : Компилятор AspectJ принимает в качестве входных данных как исходный код вашего аспекта, так и нашего приложения и создает файлы класса woven в качестве выходных данных
  2. Посткомпиляционное плетение : Это также известно как двоичное плетение. Он используется для переплетения существующих файлов классов и файлов JAR с нашими аспектами
  3. Плетение во время загрузки : Это точно так же, как и предыдущее двоичное плетение, с той разницей, что плетение откладывается до тех пор, пока загрузчик классов не загрузит файлы классов в JVM

Для получения более подробной информации о самом AspectJ перейдите к этой статье .

Поскольку AspectJ использует время компиляции и время загрузки класса, Spring AOP использует время выполнения .

При плетении во время выполнения аспекты сплетаются во время выполнения приложения с использованием прокси целевого объекта – с использованием динамического прокси JDK или прокси CGLIB (которые обсуждаются в следующем пункте):

3.3. Внутренняя структура и применение

Spring AOP-это платформа AOP на основе прокси-сервера. Это означает, что для реализации аспектов целевых объектов он создаст прокси-серверы этого объекта. Это достигается одним из двух способов:

  1. Динамический прокси JDK – предпочтительный способ для Spring AOP. Всякий раз, когда целевой объект реализует хотя бы один интерфейс, будет использоваться динамический прокси-сервер JDK
  2. Прокси CGLIB – если целевой объект не реализует интерфейс, можно использовать прокси CGLIB

Мы можем узнать больше о механизмах проксирования Spring AOP из официальных документов .

Аспект, с другой стороны, ничего не делает во время выполнения, поскольку классы компилируются непосредственно с аспектами.

И поэтому, в отличие от Spring AOP, он не требует каких-либо шаблонов проектирования. Чтобы вплести аспекты в код, он вводит свой компилятор, известный как AspectJ compiler (ajc), с помощью которого мы компилируем нашу программу, а затем запускаем ее, предоставляя небольшую (< 100K) библиотеку времени выполнения.

3.4. Точки соединения

В разделе 3.3 мы показали, что Spring AOP основан на прокси-шаблонах. Из-за этого он должен подклассировать целевой класс Java и соответственно применять сквозные проблемы.

Но у этого есть ограничение. Мы не можем применять сквозные проблемы (или аспекты) к классам, которые являются “окончательными”, потому что они не могут быть переопределены, и, таким образом, это приведет к исключению во время выполнения.

То же самое относится к статическим и конечным методам. Весенние аспекты не могут быть применены к ним, потому что они не могут быть переопределены. Следовательно, Spring AOP из-за этих ограничений поддерживает только точки соединения выполнения метода.

Тем не менее, AspectJ вплетает сквозные проблемы непосредственно в фактический код перед выполнением. В отличие от Spring AOP, он не требует подкласса целевого объекта и, таким образом, поддерживает многие другие точки соединения. Ниже приводится краткое описание поддерживаемых точек соединения:

Вызов метода Да Нет
Выполнение метода Да Да
Вызов конструктора Да Нет
Выполнение конструктора Да Нет
Выполнение статического инициализатора Да Нет
Инициализация объекта Да Нет
Ссылка на поле Да Нет
Назначение полей Да Нет
Выполнение обработчика Да Нет
Выполнение рекомендаций Да Нет

Также стоит отметить, что в Spring AOP аспекты не применяются к методу, вызываемому в том же классе.

Это очевидно, потому что, когда мы вызываем метод в том же классе, мы не вызываем метод прокси-сервера, который предоставляет Spring AOP. Если нам нужна эта функциональность, то мы должны определить отдельный метод в разных компонентах или использовать AspectJ.

3.5. Простота

Spring AOP, очевидно, проще, потому что он не вводит никакого дополнительного компилятора или ткача между нашим процессом сборки. Он использует плетение во время выполнения, и поэтому он легко интегрируется с нашим обычным процессом сборки. Хотя это выглядит просто, он работает только с бобами, которые управляются весной.

Однако, чтобы использовать AspectJ, мы должны ввести компилятор AspectJ (ajc) и повторно упаковать все наши библиотеки (если только мы не переключимся на посткомпиляцию или ткачество во время загрузки).

Это, конечно, сложнее, чем первое, потому что в нем представлены инструменты Java AspectJ (которые включают компилятор (ajc), отладчик (ajdb), генератор документации (ajdoc), браузер структуры программы (ajbrowser)), которые нам необходимо интегрировать либо с нашей IDE, либо с инструментом сборки.

3.6. Производительность

Что касается производительности, плетение во время компиляции намного быстрее, чем плетение во время выполнения . Spring AOP-это платформа на основе прокси-серверов, поэтому создание прокси-серверов происходит во время запуска приложения. Кроме того, существует еще несколько вызовов методов для каждого аспекта, что негативно влияет на производительность.

С другой стороны, AspectJ вплетает аспекты в основной код перед выполнением приложения, и, таким образом, нет дополнительных накладных расходов во время выполнения, в отличие от Spring AOP.

По этим причинам бенчмарки предполагают, что AspectJ почти в 8-35 раз быстрее, чем Spring AOP.

4. Резюме

В этой краткой таблице суммируются ключевые различия между Spring AOP и AspectJ:

Реализовано с использованием расширений языка программирования Java Реализовано в чистом Java
Нуждается в компиляторе AspectJ (ajc), если не настроен LTW Нет необходимости в отдельном процессе компиляции
Плетение во время выполнения недоступно. Поддерживает плетение во время компиляции, после компиляции и во время загрузки Доступно только плетение во время выполнения
Более мощный – может создавать поля, методы, конструкторы, статические инициализаторы, конечный класс/методы и т. Д… Менее мощный – поддерживает только плетение на уровне метода
Может быть реализован на всех объектах домена Может быть реализован только на бобах, управляемых контейнером Spring
Поддержка всех точечных разрезов Поддерживает только точечные вырезы выполнения метода
Аспекты вплетаются непосредственно в код перед выполнением приложения (до выполнения) Прокси создаются из целевых объектов, и аспекты применяются к этим прокси
Лучшая Производительность Намного медленнее, чем AspectJ
Сравнительно сложнее, чем весенний АОП Легко учиться и применять

5. Выбор правильной структуры

Если мы проанализируем все аргументы, приведенные в этом разделе, мы начнем понимать, что дело вовсе не в том, что одна структура лучше другой.

Проще говоря, выбор сильно зависит от ваших требований:

  • Фреймворк: Если приложение не использует Spring framework, то у нас нет другого выбора, кроме как отказаться от идеи использования Spring AOP, потому что оно не может управлять ничем, что находится вне досягаемости контейнера spring. Однако, если ваше приложение создано полностью с использованием Spring framework, мы можем использовать Spring AOP, поскольку его легко изучать и применять
  • Гибкость: Учитывая ограниченную поддержку точек соединения, Spring AOP не является полным решением AOP, но он решает наиболее распространенные проблемы, с которыми сталкиваются программисты. Хотя, если мы хотим копнуть глубже и использовать AOP в максимальной степени и хотим получить поддержку из широкого спектра доступных точек соединения, то AspectJ-это выбор
  • Производительность: Если мы используем ограниченные аспекты, то существуют тривиальные различия в производительности. Но иногда бывают случаи, когда приложение имеет более десятков тысяч аспектов. Мы не хотели бы использовать плетение во время выполнения в таких случаях, поэтому было бы лучше выбрать AspectJ. Известно, что Aspect в 8-35 раз быстрее, чем Spring AOP
  • Лучшее из обоих: Оба этих фреймворка полностью совместимы друг с другом. Мы всегда можем воспользоваться преимуществами Spring AOP, когда это возможно, и по-прежнему использовать AspectJ для получения поддержки точек соединения, которые не поддерживаются первым

6. Заключение

В этой статье мы проанализировали как Spring AOP, так и AspectJ в нескольких ключевых областях.

Мы сравнили два подхода к AOP как по гибкости, так и по тому, насколько легко они будут соответствовать нашему приложению.