Spring AOP против AspectJ

178

У меня сложилось впечатление, что Spring AOP лучше всего использовать для конкретных задач приложений, таких как безопасность, ведение журналов, транзакции и т. Д., Поскольку он использует пользовательские аннотации Java5 в качестве основы. Тем не менее, AspectJ выглядит более дружелюбным дизайном.

Кто-нибудь может выделить различные плюсы и минусы использования Spring AOP против AspectJ в приложении Spring?

babydudecoder
источник
3
Что делать, если в Spring есть аннотация, но также есть и в Java? Ява. Та же логика применяется к этой функциональности. Весна - это Весна. здесь сегодня прошло завтра. (Помните, люди использовали Struts некоторое время до весны). AspectJ является предпочтительным долговременным решением. Это переживет весну. Я не отклоняю Spring, просто говорю, для этого аспекта ...: -;
Inor

Ответы:

236

Spring-AOP Плюсы

  • Его проще использовать, чем AspectJ, поскольку вам не нужно использовать LTW ( ткачество во время загрузки ) или компилятор AspectJ.

  • Он использует шаблон Proxy и шаблон Decorator

Spring-AOP Минусы

  • Это AOP на основе прокси, поэтому в основном вы можете использовать только точки соединения для выполнения метода.
  • Аспекты не применяются при вызове другого метода в том же классе.
  • Там может быть немного времени выполнения.
  • Spring-AOP не может добавить аспект к чему-либо, что не создано фабрикой Spring

AspectJ Pros

  • Это поддерживает все точки соединения. Это значит, что вы можете делать все что угодно.
  • Время выполнения меньше, чем у Spring AOP.

AspectJ Минусы

  • Быть осторожен. Проверьте, связаны ли ваши аспекты только с тем, что вы хотели соткать.
  • Вам необходим дополнительный процесс сборки с AspectJ Compiler или нужно настроить LTW (время загрузки)
Whiteship
источник
20
@Configurable требует использования AspecJ через Spring. Из документов:If you need to advise objects not managed by the Spring container (such as domain objects typically), then you will need to use AspectJ.
HDave
7
для меня еще одним доводом против этого являются нечитаемые длинные трассировки стека из-за подхода на основе прокси
wrm
1
Непонятная часть в ответе: как небольшая нагрузка на время выполнения для одного инструмента и возможность небольшой накладной на время для другого?
Мореаки
16
@Moreaki: Он сказал «немного накладных расходов» как мошенник и «немного накладных расходов» как профессионал. Единственное различие «а» очень важно - на английском языке «маленький» означает «некоторые», а «маленький» означает «почти нет».
Вуек
1
Просто быстрое сомнение - в ваших Spring AOP Pros (2-й пункт) - если мы будем использовать аннотацию @Aspect весной, это будет аспектJ AOP, просто интересно, в этом случае будет ли он использовать Proxy (время выполнения) или модификацию байтов (компилировать время). Потому что у меня сложилось впечатление, что AspectJ - это время компиляции, а Spring AOP - это время выполнения AOP. Просьба помочь
Pedantic
21

Помимо того, что другие заявили - просто перефразировать there are two major differences:

  1. Один из них связан с типом ткачества.
  2. Другой к определению точки соединения.

Spring-AOP: время выполнения через прокси с использованием концепцииdynamic proxy if interface exists or cglib library if direct implementation provided.

AspectJ: Плетение времени компиляции, AspectJ Java Tools(ajc compiler)если доступен исходный текст или сплетение посткомпиляции (с использованием скомпилированных файлов). Кроме того, можно включить время загрузки с помощью Spring - ему нужен aspectjфайл определения и гибкость.

Плетение времени компиляции может предложить преимущества производительности (в некоторых случаях), а также joinpoint definition in Spring-aop is restricted to method definition only which is not the case for AspectJ.

techzen
источник
20

Дополнительное примечание: если важна производительность при высокой нагрузке, вам понадобится AspectJ, который в 9-35 раз быстрее Spring AOP . 10 нс против 355 нс может показаться не таким уж большим, но я видел людей, использующих множество аспектов. 10K стоит аспектов. В этих случаях ваш запрос может затронуть тысячи аспектов. В этом случае вы добавляете ms к этому запросу.

Смотрите критерии .

Джозеф Ласт
источник
18

Руководство пользователя Spring даст много информации прямо изо рта лошади.

Глава 6.4 - Выбор стиля объявления AOP для использования для вас уже устарел, поскольку в нем обсуждаются плюсы и минусы обоих.

Пункт 6.1.2 - Возможности Spring AOP и цели и главы 6.2 - Поддержка @Aspect и 6.8 - Использование AspectJ с приложениями Spring должно быть особенно интересным.

elhoim
источник
14

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

АОП является одной из наиболее важных частей структуры.

Ключевым моментом для понимания того, как работает AOP в Spring, является то, что когда вы пишете Aspect с помощью Spring, мы инструментируем платформу с созданием прокси для ваших объектов с помощью, JDKDynamicProxyесли ваш бин реализует интерфейс, или через CGLIB, если ваш бин не реализует какие-либо интерфейс. Помните, что вы должны иметь cglib 2.2 в вашем пути к классам, если вы используете Spring до версии 3.2. Начиная с Spring 3.2 это бесполезно, потому что в ядро ​​был включен cglib 2.2.

Инфраструктура при создании компонента создаст прокси-сервер, который обернет ваши объекты и добавит сквозные задачи, такие как безопасность, управление транзакциями, ведение журнала и так далее.

Таким образом, создание прокси будет применяться, начиная с выражения pointcut, которое инструментирует платформу, чтобы решить, какие компоненты и методы будут созданы как прокси. Совет будет более ответственным, чем за ваш код. Помните, что в этом процессе pointcut захватывает только открытые методы, которые не объявлены как final.

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

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

Как и в AspectJ, вы можете использовать время загрузки в SpringAOP. Вы можете извлечь выгоду из этой функции весной, реализованной с помощью агента и специальных конфигураций, @EnabledLoadWeavingили в XML. Вы можете использовать пространство имен в качестве примера. Однако в Spring AOP вы не можете перехватить все случаи. Например, newкоманда не поддерживается в Spring AOP.

Однако в Spring AOP вы можете извлечь выгоду из использования AspectJ через использование aspectofфабричного метода в компоненте конфигурации Spring.

По той причине, что Spring AOP - это в основном прокси, созданный из контейнера, поэтому вы можете использовать AOP только для Spring Bean. В то время как с AspectJ вы можете использовать аспект во всех ваших бобах. Другая точка сравнения - отладка и предсказуемость поведения кода. В Spring AOP все задание выполняется с помощью компилятора Java, а аспекты являются очень хорошим способом создания прокси для вашего компонента Spring. В AspectJ, если вы модифицируете код, вам нужно больше компилировать, и понять, где сплетены ваши аспекты, может быть сложно. Даже выключить ткачество весной проще: с помощью пружины вы удаляете аспект из вашей конфигурации, перезапускаете, и это работает. В AspectJ вы должны перекомпилировать код!

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

Я надеюсь, что этот обзор AspectJ и Spring AOP поможет вам понять разницу двух зелий

Валерио Вауди
источник
0

Важно учитывать, будут ли ваши аспекты критически важными и где будет развернут ваш код. Spring AOP будет означать, что вы полагаетесь на ткачество во время загрузки. Это может не привести к переплетению, и по моему опыту это означает, что зарегистрированные ошибки могут существовать, но это не помешает запуску приложения без кода аспекта [Я хотел бы добавить предостережение о том, что возможно настроить его таким образом, чтобы это не кейс; но я лично не знаю об этом ]. Ткачество во время компиляции позволяет избежать этого.

Кроме того, если вы используете AspectJ в сочетании с aspectj-maven-plugin, то вы сможете запускать модульные тесты для своих аспектов в среде CI и уверены, что встроенные артефакты проверены и правильно сплетены. Хотя вы, безусловно, можете писать модульные тесты на основе Spring, у вас все еще нет гарантии, что развернутый код будет тем, который был протестирован в случае сбоя LTW.

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

Пять лет назад я был более склонен к настройке AOP, настроенной Spring, по той простой причине, что с ней было проще работать и меньше шансов разжечь мою IDE. Однако, поскольку вычислительная мощность и доступная память увеличились, это стало гораздо менее важной проблемой, и использование CTW с помощью aspectj-maven-plugin стало лучшим выбором в моей рабочей среде на основании причин, которые я изложил выше.

kcampbell
источник
0

Эта статья также имеет хорошее объяснение по теме.

Spring AOP и AspectJ имеют разные цели.

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

С другой стороны, AspectJ является оригинальной технологией AOP, которая направлена ​​на предоставление полного решения AOP.

GCE
источник
0

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

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

Jerry Hsu
источник