AOP@Work: Сравнение инструментальных программ для AOP, часть 1

Механизмы языка

Пришло время технологии АОП. Но как выбрать нужный инструмент для ваших проектов? В этой первой статье нового цикла AOP@Work эксперт по аспектно-ориентированному программированию Мик Керстен (Mik Kersten) сравнивает четыре ведущих инструмента АОП (AspectJ, AspectWerkz, JBoss AOP и Spring AOP), что должно помочь вам определиться с выбором. В первой части статьи автор рассматривает механизмы языка инструментальных программ и альтернативы, предлагаемые различными подходами. Обратите внимание, что в этой статье обсуждается также недавно анонсированное слияние проектов AspectJ и AspectWerkz.

Mik Kersten , Архитектор инструментальных средств АОП и консультант, University of British Columbia

Мик Керстен (Mik Kersten) является ведущим экспертом по аспектно-ориентированному программированию и участником проектов AspectJ и AJDT eclipse.org. В качестве ученого-исследователя Xerox PARC он создал IDE-поддержку для AspectJ. Он заканчивает получение степени Ph.D. в University of British Columbia, где делает IDE более аспектно-ориентированным. Он также консультирует компании, создающие средства разработки, по вопросам использования и поддержки аспектно-ориентированной технологии.



08.02.2005

Аспектно-ориентированное программирование (АОП) становится все более популярным на платформе Java™. Чем больше говорят об АОП в прессе и на конференциях, тем больше появляется инструментальных средств и реализаций технологии. И хотя ясно, что АОП является дополнением к объектно-ориентированному программированию, менее очевидно, как Java-разработчики должны оценить имеющееся многообразие АОП-средств, особенно при наличии компромиссов, присущих реализации любой новой технологии.

В этой состоящей из двух частей статье, первой в новом цикле статей developerWorks, посвященных АОП, я рассмотрю современное состояние дел в инструментальных программах АОП, приведу сравнение самых зрелых подходов к технологии (AspectJ, AspectWerkz, JBoss AOP и Spring AOP ), а также коснусь вопросов, связанных с адаптацией каждого из них. Я также рассмотрю последствия недавно анонсированного слияния проектов AspectJ и AspectWerkz (см. раздел "Ресурсы").

Эта статья не является ведением в АОП или учебником по какой-либо конкретной реализации АОП. Она представляет собой обзор наиболее используемых АОП-технологий, доступных в настоящее время. Детальное обсуждение компромиссов, присущих механизмам языка каждого инструмента, и поддержки этих инструментов помогут вам выбрать подход, наиболее соответствующий вашим проектам. Определенные здесь критерии должны также упростить оценку появляющихся новых версий АОП-инструментов и их функциональных возможностей. Список последних статей developerWorks, посвященных знакомству с АОП, приведен в разделе "Ресурсы".

Обратите внимание, что эта статья состоит из двух частей, опубликованных для удобства одновременно. Первая часть посвящена теме реализации механизмов языка АОП в четырех ведущих инструментах. В эту тему входят сходства и различия между синтаксисом аспектов и выразительностью pointcut (срезов точек), а также набор механизмов для объявления аспектов. Во второй части рассматриваются вопросы интеграции основных реализаций АОП с существующими средами разработки, инструментальными программами и библиотеками. В ней рассматриваются компоновщики аспектов (weavers), подключаемые модули IDE, вопросы масштабируемости, направление развития АОП-средств, а также обсуждается недавнее слияние проектов AspectJ и AspectWerkz.

Сужение выбора

АОП является новой технологией и, следовательно, не все имеющиеся на данный момент инструментальные средства достаточно подготовлены для коммерческой разработки. Одним из основных факторов в определении зрелости является распространенность среди пользователей. Перед тем как новая технология программирования может рассматриваться для коммерческого использования, она должна пройти закалку ответной реакцией сообщества активных пользователей. В таблице 1 показаны доступные в настоящее время АОП-инструменты, перечисленные на сайте aosd.net (см. раздел "Ресурсы"). Количество пользовательских сообщений для каждого инструмента дает представление об их пользовательской базе. (Действительное число сообщений не приводится, поскольку статистика за один месяц может быть обманчива.)

Таблица 1. Количество пользовательских сообщений по AOP-инструментам в ноябре 2004

Об этом цикле статей

Цикл статей AOP@Work предназначен для разработчиков, обладающих некоторыми основными знаниями аспектно-ориентированного программирования и желающих расширить или углубить их (материалы по основам АОП можно найти в разделе "Ресурсы"). Как и большинство статей developerWorks, статьи этого цикла очень практичны: из каждой статьи вы получите новые знания, которые можно сразу же использовать.

Каждый из авторов статей этой серии был выбран из-за превосходных знаний или компетентности в АОП. Многие авторы являются участниками рассматриваемых в статьях проектов или инструментальных средств. Каждая статья рецензируется для гарантии справедливости и точности выраженной в ней точки зрения.

Связывайтесь, пожалуйста, с авторами лично, чтобы прокомментировать их статьи или задать вопрос о них. Чтобы прокомментировать цикл статей в целом, вы можете связаться с ее ведущим Николасом Лесицки (Nicholas Lesiecki). Дополнительные материалы по АОП можно найти в разделе "Ресурсы".

О статье

Эта статья предназначена не для освещения какого-либо одного инструмента, а для критичного и непредвзятого выявления сильных и слабых сторон каждого инструмента. Хотя автор является участником проекта AspectJ, были проведены консультации с лидерами проектов других АОП-инструментов, чтобы гарантировать справедливое представление обсуждаемых технологий.

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

И хотя не вошедшие в четверку лидеров АОП-инструменты могут быть технологически прекрасными, отсутствие мощной пользовательской базы указывает, что они еще не прошли тест принятия пользователями. Несмотря на то, что на момент написания статьи эти инструменты не готовы для коммерческого использования, их стоит рассмотреть в дальнейшем. Из таблицы также видно, что АОП-инструменты, основанные не на Java-платформе, менее распространены, чем основанные на Java, хотя надо отметить, что сообщества пользователей средств для .NET и C++ постоянно увеличиваются.

Основываясь на данных таблицы 1, вы можете увидеть, что AspectJ, AspectWerkz, JBoss AOP и Spring AOP являются лидерами с точки зрения принятия пользователями. Все эти инструменты являются проектами с открытым исходным кодом и подходят для коммерческой разработки. Они перечислены здесь в алфавитном порядке, вместе с датами выхода версий V1.0:

  • AspectJ - Выпущен в 2001 командой AOP фирмы Xerox PARC. В настоящее время находится на eclipse.org и поддерживается IBM. Рассматриваемый номер версии - 1.2.1.
  • AspectWerkz - Выпущен в 2002 и поддерживается BEA Systems. Рассматриваемый номер версии - 2.0RC2.
  • JBoss AOP - Выпущен в 2004 как дополнение к среде сервера приложений JBoss. Рассматриваемый номер версии - 1.0.
  • Spring AOP - Выпущен в 2004 как дополнение к среде Spring. Рассматриваемый номер версии - 1.1.3.

Все о точках соединений

Каждый рассматриваемый в этой статье АОП-инструмент использует модель точек соединений (join point) и механизмы для явного объявления пересекающейся структуры программы. И хотя реализации этой среды очень похожи в разных инструментах, важно понимать внутренние механизмы, для того чтобы оценить каждый подход. В данном разделе я сделаю обзор модели точек соединения в АОП и механизмов языка, использующих ее.

Разрешение механизмов

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

Точка соединения - это место, где пересекаются основная программа и аспект. Статические точки соединения позволяют аспектам определить новые члены класса. В динамических точках соединения выполняющийся аспект встречается с выполняющейся программой. Например, обычные Java-программы выполняют точки соединения, такие как вызовы методов и установки полей. Рассмотрим, например, процесс мониторинга активности, которая изменяет состояние Account, обсуждавшийся в книге Рамниваса Лэдада (Ramnivas Laddad) "AspectJ in Action" (см. раздел Ресурсы). На циклограмме, показанной на рисунке 1, выделено несколько динамических точек соединения, которые являются результатом операций с Account.

Рисунок 1. UML-циклограмма с выделенными динамическими точками соединения

Приведенные ниже цифры соответствуют цифрам на рисунке:

  1. Точки соединения Method execution (выполнение метода) соответствуют циклу жизни метода до возврата из него.
  2. Control flows (потоки управления) объединяют различные точки соединения, которые возникают внутри последовательности управляющего потока; в этом случае последовательность ниже вызова метода debit() описывает все точки соединения, возникающие внутри вызова debit().
  3. Точки соединения Field access (доступ к полям) соответствуют чтению и записи полей; в данном случае - производимое в классе Account присваивание поля name.

Слияние проектов AspectJ и AspectWerkz

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

Важно отметить, что AspectWerkz не исчезает. Он становится альтернативным способом написания AspectJ-программ и переименован в @AspectJ style. Как вы узнаете далее, синтаксис является основным фактором различий между АОП-реализациями, в то время как основные механизмы АОП часто очень похожи. Сходство AspectWerkz и AspectJ позволило двум технологиям объединить усилия. Слияние предложит большую гибкость в выборе синтаксиса аспектов, сохраняя одновременно ключевые преимущества, такие как статическое типизирование и хорошую поддержку инструментов. Подробная информация по слиянию и соответствующая документация доступна в разделе "Ресурсы". Поскольку в данной статье внимание концентрируется на инструментах, которые вы можете начать использовать уже сегодня, приведенные критерии и альтернативы также будут учтены в будущий версиях, таких как AspectJ 5.

Pointcuts (срезы точек), advice (рекомендации) и объявления inter-type

АОП-инструменты предоставляют механизм для указания набора точек соединения, называемых pointcut (срезами точек). Механизм advice указывает, какое действие нужно выполнить во время совпадения pointcut при выполнении программы. Кроме того, объявления inter-type (известные также под названием открытые классы или смешения (mixins)) обеспечивают средство объявления дополнительных членов существующих типов. Все вместе pointcuts, advice и объявления inter-type позволяют АОП-языкам явно выразить пересекающиеся процессы. Объявление аспекта может содержать эти три типа членов в дополнение к обычным полям и методам Java. Аспект представляет модуль хорошо скомпонованной пересекающейся структуры. Как вы увидите ниже, реализация этих механизмов отличается в разных АОП-инструментах. В основе каждого подхода, однако, лежит механизм доступа, создания, именования и абстрагирования точек соединений.

Pointcut могут описывать наборы точек соединения посредством явного перечисления (enumeration). В примере будут приведены три вызова метода в Account, показанные на рисунке 1. И хотя перечисление может быть полезным, часто более удобно выразить набор точек соединения при помощи структурированных свойств. Такие основанные на свойствах pointcut могут указать набор точек соединения, соответствующих фразе "каждый вызов подтипа Account", избавив программиста от необходимости перечислять эти подтипы. Это гарантирует, что когда в систему добавится новый класс, расширяющий Account, он автоматически будет соответствовать pointcut.

Поддержка композиции pointcut дает возможность комбинировать простые pointcut в более сложные. Например, вы можете ограничить действие pointcut всех вызовов Account только на те, которые были сделаны из конкретного класса или потока управления. Механизм именования poincut облегчает читабельность и композицию. Поддержка абстракции и конкретизации облегчает создание обобщенных библиотек, которые могут быть определены независимо от pointcut конкретного приложения, к которому они будут применены. Наконец, поддержка показа состояния точки соединения в pointcut дает возможность для advice получить доступ к таким вещам, как выполняющиеся объекты или параметры методов. В следующем разделе мы увидим эти механизмы в работе каждого из четырех инструментальных средств.


Сравнение аспектов

Как я уже говорил, внутренним механизмом всех АОП-инструментов является модель точек соединения и концепция pointcut, advice и объявлений inter-type. Основным отличием между этими инструментами, которое вы можете обнаружить, является способ написания объявлений аспектов и их использования. Для описания аспектов инструментальные средства применяют три способа: использование Java-подобного кода, аннотаций или XML. Для некоторых разработчиков привычность аспектов, написанных на языке программирования Java, будет иметь большую важность, чем некоторые недостатки подхода такого расширения языка, которые мы рассмотрим в следующем разделе. Для других интеграционные преимущества при использовании аннотаций и XML будут перевешивать недостатки работы с pointcut как строками.

В этом разделе я буду использовать общий пример, для того чтобы подчеркнуть различия способов объявления аспектов каждого инструмента. Рассмотрим пример политики аутентификации для класса Account, показанного на рисунке 1. При объектно-ориентированной реализации вы должны были бы, вероятнее всего, увидеть вызовы процедуры аутентификации разбросанными по методам класса Account, а так же и в любых других классах, требующих аутентификации. В реализации АОП вы можете заключить это поведение явным образом в одном аспекте и не изменять код, управляющий экземплярами класса Account. Независимо от используемого для их объявления инструмента этот аспект должен иметь следующие характеристики:

  • pointcut, охватывающий выполнение всех методов public класса banking.Account
  • Средство для ссылки к аутентифицируемому Account
  • Advice, вызывающий аутентификацию для Account, и точки соединения, указанные в pointcut

Теперь посмотрим, как каждый из ведущих АОП-инструментов применит этот аспект.

AspectJ

Объявление аспекта находится в объявлении параллельного класса AspectJ на языке Java, как показано на рисунке 2. Поскольку AspectJ представляет собой расширение синтаксиса и семантики языка Java, он предоставляет свой собственный набор ключевых слов для работы с аспектами. В дополнение к полям и методам объявление аспекта AspectJ содержит члены pointcut и advice. Pointcut в примере использует модификатор и групповой символ для выражения "все методы public". Доступ к account обеспечивается параметром pointcut. Advice использует этот параметр, а pointcut указывает его, используя this(account). Это имеет эффект заключения в себе объекта Account, на котором выполняется метод. Во всем остальном тело advice аналогично телу метода. Advice может содержать код аутентификации, либо, как в данном случае, может вызывать еще один метод.

Рисунок 2. Аспект в AspectJ

Компоновка программы AspectJ аналогична компоновке программы Java. Она включает в себя вызов инкрементного компилятора AspectJ, который создает все исходные тексты проекта, включая обычный Java-код. Запуск программы AspectJ тоже аналогичен запуску Java-программы; небольшая библиотека aspectjrt.jar должна быть добавлена в classpath. Для конфигурирования того, какие аспекты применить к системе, вы должны добавить или удалить их из списка включений, передаваемого компилятору, либо при помощи IDE-средств, либо непосредственно в файле включений с расширением ".lst" при работе в среде Ant или в командной строке. Отмечу, что во второй части я подробно рассмотрю процесс компоновки АОП-программ, так же как и концепцию компоновки (weaving) аспектов.

AspectWerkz

Ключевым отличием AspectWerkz от AspectJ является то, что Authentication в нем представляет собой обычный Java-класс, а не аспект. AspectWerkz, JBoss AOP и Spring AOP добавляют семантику аспекта без изменения синтаксиса языка программирования Java. AspectWerkz предоставляет два способа для создания АОП-объявлений. Наиболее часто используемым являются аннотации, которые могут иметь вид Java V5.0, как показано на рисунке 3, или вид Javadoc для совместимости с J2SE V1.4. AspectWerkz поддерживает также альтернативный способ объявления аспекта, основанный на XML. XML-стиль аналогичен способу, применяемому в JBoss AOP, который описан ниже, и размещает объявления аспектов в отдельном XML-файле.

Обратите внимание, что advice представляет собой объявление обычного метода. По соглашению он считается другим типом объявления метода, поскольку не должен вызываться явно, а запускаться автоматически при совпадении конкретного pointcut. Объявления pointcut в AspectWerkz представляют собой строковые значения, присоединенные к "методам" pointcut или находящиеся отдельно в XML. В результате этого отсутствует механизм импорта для pointcut, и все типизированные ссылки должны быть полностью определены. Доступ к выполняющемуся объекту Account аналогичен доступу в AspectJ. Обратите внимание, что синтаксис запланированного @AspectJ очень похож на синтаксис аннотаций AspectWerkz.

Рисунок 3. Аспект в AspectWerkz

Компоновка программы в AspectWerkz включает в себя стандартную компоновку Java, за которой следует пост-обработка. Для запуска программы AspectWerkz вы должны поместить библиотеки AspectWerkz в ваш classpath. Файл aop.xml конфигурирует включение аспектов в систему в случае, когда используются не подключаемые аспекты.

JBossAOP

Основанный на XML стиль объявления аспекта JBoss AOP показан на рисунке 4. JBoss поддерживает также стиль аннотаций, аналогичный показанному на рисунке 3. В XML-стиле объявления аспекта, pointcut и advice делаются в XML. Advice реализуется с использованием обычных методов Java, которые вызываются средой JBoss AOP. И pointcuts и их связи с advice объявляются в аспекте при помощи XML-аннотаций. Вместо явного связывания параметра Account JBoss обеспечивает отраженный доступ к выполняющимся в данный момент объектам, требуя приведения к соответствующему типу. Отмечу, что готовящаяся новая версия JBoss предоставит статическое типизирование параметров pointcut для решения этого вопроса.

Рисунок 4. Аспект в JBoss AOP

Компоновка аспекта в JBoss включает в себя только обычную компоновку Java. Перехватывающая среда JBoss AOP времени исполнения управляет совпадением pointcut и вызовом advice. Требуется некоторое конфигурирование запуска и переменной classpath, но подключаемый модуль JBoss AOP IDE делает это конфигурирование незаметным для пользователя. Аспекты конфигурируются в файле jboss-aop.xml.

SpringAOP

Изучая пример Spring AOP, изображенный на рисунке 5, вы можете заметить, что здесь XML задействован в большей степени, чем в предыдущих примерах. Так же как и в JBoss AOP, реализация advice в Spring представляет собой метод Java со специальными параметрами, который будет вызываться средой Spring. XML объявляет accountBean, предоставляющий среде Spring доступ к объектам Account, включая используемый для advice перехватчик, advisor и его шаблон соответствия, а также advice before для применения к этому шаблону.

Рисунок 5. Аспект в Spring AOP

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


Синтаксические отличия

Как показано на приведенных выше рисунках, ключевыми отличиями АОП-инструментов являются способы объявления аспектов. AspectJ является расширением языка Java, что позволяет объявлять аспекты полностью в коде. AspectWerkz и JBoss AOP вынуждают вас аннотировать ваш Java-код метаданными аспектов или объявлять аспекты в отдельном XML-файле. В Spring AOP вы объявляете аспект полностью в XML. В результате этого программирование аспектов может выглядеть совершенно по-разному в каждом из трех подходов. Объявления аспектов и pointcut в стиле AspectJ будет выглядеть как обычный Java-код. Их объявления в стиле аннотаций JBoss AOP или AspectWerkz будут выглядеть как дополнительные теги в существующих элементах языка Java. И, наконец, в Spring AOP, а также в XML-стиле AspectWerkz и JBoss AOP, они будут выглядеть как отдельные декларативные конструкции языка XML.

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

Каков ваш стиль?

Независимо от выбранного вами АОП-инструмента, работа с advice заключается просто в работе с Java-кодом. Различия становятся заметными при наступлении момента изменения pointcut. При работе в XML-стиле, например в Spring AOP, изменение pointcut включает в себя переход из advice в соответствующее объявление pointcut в XML-файле. Положительным моментом является то, что этот подход локализует все ваши конфигурации pointcut и аспектов, но для вас может быть очень утомительным редактирование большого количества advice и pointcut, а также постоянное переключение между Java и XML-файлами.

Если вы используете стиль аннотаций, предлагаемый AspectWerkz или JBoss AOP, то сможете переместить значения выражений pointcut из XML в аннотации Java-члена. Это заметно облегчит совместную работу с телом advice и pointcut. Если вы выберете стиль кодирования AspectJ, вы обнаружите, что работа с pointcut выглядит как работа с кодом, а не с неструктурированными строковыми значениями. Все, что вы ожидаете от Java-кода (например операторы "import"), также будет работать с pointcut. В противоположность этому, вы всегда должны указывать типы ссылок в pointcut при использовании XML и аннотаций в AspectWerkz, JBoss AOP и Spring AOP.

Лаконично или многословно?

Стиль объявления аспектов имеет сильное влияние на то, как выглядит работа с аспектами в каждом инструменте. Например, инструменты, поддерживающие объявления аспектов в XML, предоставляют вам возможность конфигурировать способы применения аспектов в одном и том же XML-файле. В предыдущем разделе я показал объявления только pointcut и аспектов, но объявления inter-type также зависят от выбранного стиля. В AspectJ объявления методов inter-type практически идентичны объявлениям нормальных методов, а ссылка на них производится как обычно. При других подходах, при помощи аннотаций или XML, добавляются новые методы, при этом указывается, что класс расширяет дополнительный класс mixin и наследует эти дополнительные члены. Обратите внимание, что в настоящее время AspectJ является единственным средством, обеспечивающим механизм статического форсирования (static enforcement), использующий pointcut. В таблице 2 приведено сравнение способов использования инструментами ключевых элементов синтаксиса АОП.

Таблица 2. Сравнение синтакcиса основных АОП-инструментов

Из объявлений аспектов на рисунках 2-5 видно, что стиль кода является наиболее лаконичным подходом к работе с АОП-объявлениями. Он не требует именования advice, поскольку advice не предназначен для явного вызова. Стиль кода не требует явного связывания advice и pointcut, как в XML-стилях, или оператора return, требуемого в "методе" AspectWerkz pointcut. Расширения синтаксиса языка Java в AspectJ предоставляют вам возможность непосредственно выражать подробные схемы взаимодействия, которые вы можете увидеть в XML на рисунках 3 и 4. Написание аспектов в AspectJ в большой степени выглядит как написание Java-кода, исключающим чрезмерный набор текста, что потенциально уменьшает вероятность ошибок. Обратной стороной является то, что расширение синтаксиса Java дается большой ценой; и XML-стиль и стиль аннотаций привносят свои уникальные преимущества. Наиболее заметным является предоставление контроля над связыванием pointcut и advice при использовании XML-стиля. Это может дать выгоды (при расширении и конфигурировании аспектов), которые я рассмотрю в следующем разделе вместе с компромиссами, на которые приходится идти при использовании различных стилей.

Стиль кода против стиля аннотаций и XML

Итак, должны ли вы использовать стиль кода, или объявлять аспекты при помощи аннотаций или XML? Вот обобщение преимуществ и недостатков основанного на Java-коде подхода, применяемого в AspectJ:

  • + Лаконичность синтаксиса ускоряет освоение Java-кода и приводит к меньшему объему набираемого текста и к уменьшению количества ошибок.
  • + Pointcut являются первоклассными сущностями, что значительно облегчает работу с ними.
  • - Для многих разработчиков декларативное программирование в XML более привычно, чем расширения языка Java.
  • - Привязка advice к pointcut не может контролироваться разработчиком.

Если эти выводы не привели к принятию решения, не беспокойтесь. Существует значительно больше требуемых для рассмотрения моментов, чем то, на что похоже написание аспектов в каждом стиле. Синтаксические решения возникнут опять, когда мы перейдем к рассмотрению семантики в следующем разделе; также на выбор влияет и поддержка инструментов, которую я рассмотрю во второй части.


Сходства семантики

В то время, когда существуют серьезные синтаксические отличия в стилях объявления аспектов, основы АОП-семантики остаются одинаковыми. Каждый инструмент имеет одно и то же представление о модели точек соединения, рассматривая эти точки соединения как элементарные точки в Java-программе, pointcut как механизм совпадения точек соединения, а advice как механизм указания действия, которое надо выполнить при совпадении точки соединения.

В таблицах 3 и 4 обобщается семантика каждого подхода. Вы заметите многочисленные мелкие отличия и небольшие вариации в соглашениях по именованию, но подходы сводятся к одним и тем же основным концепциям. Такая конвергенция является огромной удачей, поскольку означает, что в процессе изучения АОП можно легко переключаться с одного подхода на другой. Что еще осталось рассмотреть – это ограничения, налагаемые различиями в каждом подходе.

Назад к точкам соединения

Выразительность модели точек соединения АОП-инструментов определяет уровень модульности доступных точек соединения и то, как ищутся соответствия этих точек. Каждый АОП-инструмент предлагает множество элементарных pointcut для сопоставления точек соединения. Некоторые из этих элементарных pointcuts соответствуют точкам только определенного типа (например, точкам выполнения методов). Другие могут соответствовать любым типам точек соединения, основываясь на общем свойстве этих точек (например, все точки определенного потока управления). Типы точек соединения и их конкретные pointcut могут быть сгруппированы следующим образом:

  • Invocation – указываются при вызове или выполнении методов и других элементов кода
  • Initialization – указываются при инициализации классов и объектов
  • Access – указываются при чтении или записи полей
  • Exception handling – указываются при возникновении и обработке исключительных ситуаций и ошибок

Кроме того, поддерживаются следующие категории нетипизированных pointcut:

  • Control flow - точки соединения внутри определенных потоков управления программы
  • Containment - точки соединения, соответствующие местам в коде, находящимся внутри определенных классов и методов
  • Conditional - точки соединения, для которых является истинным указанный предикат

Как показано в таблице 3, каждый инструмент имеет немного отличающиеся реализации модели точек соединения и используемые для сопоставления этим точкам элементарные pointcut. Обратите внимание на то, что в некоторых случаях (как указано в круглых скобках) точки соединения не идентифицируются при помощи pointcut.

Таблица 3. Точки соединения и примитивные pointcut, используемые для их сопоставления

Выразительность или простота?

Главным компромиссом является выбор между выразительностью и простотой. Более полные и тонко структурированные наборы pointcut дают возможность доступа в аспектах к большему количеству точек выполнения программы. Например, аспекту, связанному с персистентностью, может понадобиться доступ к точкам соединения при инициализации объекта. Но такая полнота приводит к дополнительной сложности, как и к усложнению изучения. Многие Java-программисты не делают различий между вызовами и выполнением, и еще меньшему их числу понадобится понимание тонкостей инициализации. Кроме того, большое количество широко используемых аспектов являются вспомогательными, то есть не связанными тесно с функциональностью приложения. Общеупотребляемые вспомогательные аспекты, такие как мониторинг и ведение журналов, обычно используют только крупномодульные pointcut, такие как выполнение методов. С другой стороны, более широкий набор pointcut обладает свойством "платы по ходу действия", то есть их можно изучать при возникновении необходимости. Попытки обойтись без pointcut могут привести к необходимости пересмотра (рефакторинга) кода, например для экспонирования инициализации класса в форме методов init().

Модели точек соединения AspectJ и AspectWerkz совпадают практически полностью, и это являлось одним из ключевых моментов, сделавших возможным недавнее слияние. Модель JBoss AOP почти такая же выразительная, и в целях упрощения опускает только наименее употребляемые точки соединения. Одним заметным отличием в JBoss AOP является невозможность указания потоков управления в виде "все точки соединения, управляемые данным pointcut". Вместо этого программисты вынуждены вручную перечислять каждый вызов в интересующем стеке вызовов.

SpringAOP предлагает другой подход и целенаправленно ограничивает выразительность своей модели точек соединения. Это делает его особенно легким в изучении и полезным для крупномодульных пересекающихся (crosscutting) процессов. Готовящаяся версия будет интегрирована с AspectJ для обеспечения возможности взаимодействия с тонко настроенными механизмами пересечения.

Выразительность модели точек соединения против простоты

Будет ли ваше приложение пользоваться выгодами более выразительной модели точек соединения, предлагаемыми AspectWerkz, AspectJ и JBoss AOP, или рациональнее использовать крупномодульную модель Spring AOP? Вот обобщение внутренних свойств более выразительной модели для помощи в ваших рассуждениях:

  • - Больше учить.
  • - Только малое количество pointcut требуется для крупномодульных пересекающихся процессов и вспомогательных аспектов.
  • + Многие аспекты нельзя выразить без тонко настроенных pointcut.
  • + Можно изучать использование новых pointcut по мере их использования.

Техника языка

Я закрою дискуссию в первой части сравнения АОП-инструментов более подробным освещением языковых механизмов каждого из них. В таблице 4 приведен обзор АОП-семантики четырех инструментов. Самые существенные отличия будут рассмотрены ниже.

Таблица 4. Обзор семантик основных АОП-инструментов

Сопоставление и композиция pointcut: AspectJ, AspectWerkz и JBoss AOP предлагают одинаковую поддержку типовых шаблонов (pattern). Все они разрешают сопоставление по сигнатурам, в том числе аннотации и родовые типы (generic) в приложениях Java 5. AspectJ и AspectWerkz предлагают лаконичный способ ссылки на множественные типы (например, Account+ указывает на все подтипы объекта account). Все инструменты поддерживают сопоставления по групповым символам. Spring AOP также предлагает поддержку регулярных выражений. И хотя это может выглядеть значительным преимуществом, необходимо отметить, что в других инструментах сознательно отказались от использования регулярных выражений для того, чтобы воспрепятствовать появлению трудночитаемых и потенциально ненадежных pointcut. Операторы композиции pointcut почти идентичны для всех инструментов. Spring AOP не поддерживает отрицаний, которые обычно используются вместе с точками соединения типа containment, которые не представлены в модели Spring AOP.

Формы advice: AspectJ поддерживает больше форм advice, чем остальные, и, напротив, JBoss AOP поддерживает только одну. Любая форма advice может быть выражена формой around, так что подход JBoss не является ограничивающим, а лишь предлагает упрощение. Обратной стороной является потеря краткости, что можно увидеть на рисунке 4 в дополнительном вызове для обработки вместе с оригинальным вызовом метода, который не нужен при использовании формы before. Также обратите внимание на то, что соответствие advice обычным правилам Java (как при использовании аннотаций и XML) в некоторых случаях является проблематичным, поскольку эти правила были созданы для методов. Способность AspectJ "смягчать" исключительные ситуации для методов advice не связана с семантикой обработки исключительных ситуаций стандартного метода и может быть полезной.

Контекст точки соединения: В AspectJ и AspectWerkz динамическое состояние точки соединения может быть получено при помощи указания и связывания параметров pointcut способом, аналогичным объявлению параметров метода в языке программирования Java (см. рисунки 2 и 3). Это дает преимущество статического указания типа для контекста точки соединения. JBoss AOP и Spring AOP получают доступ к состоянию точки соединения рефлективно, что устраняет сложность связывания параметров из выражений pointcut, но за счет статического указания типов параметров. Java-программисты приучены к преимуществам статического типизирования параметров методов и получают те же преимущества от статического типизирования параметров pointcut. Как результат, есть планы обеспечить статические типы "args" в готовящейся версии JBoss AOP.

Создание экземпляра: Во всех инструментах создание экземпляра аспекта контролируется спецификаторами per. Как и ожидалось, модель создания экземпляра в Spring AOP является наиболее простой. Поддержка дополнительных механизмов создания экземпляров означает, что аспекты могут быть написаны для применения только в конкретном динамическом контексте без необходимости написания кода, который сохраняет контекст и проверяет, нужно ли применить аспект. Основными отличиями являются: AspectJ поддерживает создание экземпляра аспекта на поток управления, в то время как AspectWerkz поддерживает создание экземпляра на поток, а JBoss - на конкретную точку соединения. Что наиболее полезно - зависит от ваших требований.

Расширяемость: Расширяемость аспекта дает возможность развертывания библиотеки аспектов, которую впоследствии можно будет конкретизировать для определенного приложения. Например, библиотека аспекта может обеспечить всю логику и инфраструктуру, требуемую для мониторинга приложения. Однако при адаптации библиотеки для конкретного проекта используемые ею pointcuts должны быть расширены точками соединения, специфичными для приложения. AspectJ поддерживает расширяемость при помощи абстрактных аспектов, содержащих абстрактные pointcut и конкретные advice. Субаспекты, расширяющие их, должны конкретизировать pointcut. AspectWerkz и JBoss AOP используют значительно отличающиеся подходы и не применяют механизм абстрактных pointcut. Расширение производится путем создания подклассов аспекта и определения новых связей advice в XML или аннотациях. Явная привязка pointcut к advice дает AspectWerkz и JBoss AOP значительное преимущество в простоте расширения аспектов в новой системе без необходимости создания субклассов. Постоянно растущее количество данных об использовании библиотек аспектов определит, хуже или лучше используемая в AspectJ специальная форма АОП-наследования, чем другие подходы, использующие наследование в Java-стиле и связывание pointcut.

Каждый подход предлагает уникальный набор компромиссов в вопросах обработки языковых механизмов АОП. Обобщение этих компромиссов не представляется возможным, поскольку преимущества каждого будут проявляться для различных проектов в разной степени. Тем не менее, представленная выше информация обеспечит основные направления при выборе инструмента или во время поиска альтернатив при возникновении критических ограничений.


Заключение

Задача выбора АОП-инструмента для вашего проекта состоит в сравнении возможностей каждого подхода и стремлении не идти на большие уступки. В первой части сравнения АОП-инструментов были рассмотрены основные механизмы четырех ведущих АОП-подходов, а также их сходства и отличия.

Если бы эта статья по новой технологии модульного построения систем была подготовлена лет 10 назад, мы могли бы на этом остановиться, а вы были бы готовы написать аспект в выбранном стиле, возможно, скомпоновав его в командной строке при помощи Emacs или другого текстового редактора. Однако сейчас вы не можете рассматривать возможность принятия новой технологии без обращения пристального внимания на то, как она интегрируется в существующие средства разработки и другие инструменты.

Поэтому, во второй части статьи мы перейдем к рассмотрению влияния интеграционных факторов на выбор АОП-инструмента. Среди прочего я рассмотрю, как каждый инструмент справляется с компилированием аспекта и его компоновкой (weaving), а также их состояние с точки зрения интеграции с IDE и поддержки инструментальных средств. Я также дам сравнение основных функциональных возможностей инструментальных средств и бегло коснусь их перспектив, включая обсуждение того, чего нам можно ожидать от слияния проектов AspectJ и AspectWerkz.

Ресурсы

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Технология Java
ArticleID=96640
ArticleTitle=AOP@Work: Сравнение инструментальных программ для AOP, часть 1
publish-date=02082005