Tuesday, December 8, 2009

Видео лекция по AspectJ

Аспектно-ориентированное программирование (АОП) — парадигма программирования, основанная на идее разделения функциональности для улучшения разбиения программы на модули. Основная идея сводится к выделению сквозной функциональности, разбросанной между существующими модулями программы (классами, функциями), в отдельные аспекты, которые потом можно повторно использовать. Многие контейнеры, среди которых и Spring Framework, содержат в своем ядре АОП и используют его, а некоторые даже предоставляют свою реализацию (Spring AOP, JBoss AOP).

АОП мне понравилось своим нестандартным подходом. Всем известная единица модульности в ООП — это класс. Некий набор классов, где каждый выполняет совсем разные функции, может содержать определенную сквозную функциональность, не имеющую отношение к логике самих классов. Это может быть управление транзакциями, кеширование данных, ведение логов, уведомление пользователя и т. д. Как сделать так, чтобы функциональность не дублировалась? Можно воспользоваться самим ООП, применить наследование или агрегацию, но тогда классы все равно будут зависеть от других. Можно применить различные шаблоны проектированиявнедрение зависимостей, например, но тогда приложение становится зависимым от сторонней библиотеки, применение которой не всегда может быть оправдано. Шаблоны проектирования помогают решить большинство проблем, связанных с проектированием приложения, но что, если сам шаблон содержит, либо приводит к появлению, сквозной функциональности (например, шаблон Наблюдатель, где дублируется логика управления наблюдателями)?

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

АОП реализовано во многих языках программирования. Для Java одной из успешных реализаций является AspectJ. Для работы с ней в среде Eclipse отлично подойдет плагин AJDT. Документации по AspectJ и вообще по АОП можно найти много, но мне больше всего нравятся два источника. Первый — это AspectJ 5 Developer's Notebook. Он же содержится сразу в помощи (F1) к плагину AJDT. Второй источник — это цикл статей AOP@Work от IBM. После того, как познакомитесь с АОП, рекомендую прочитать статью AOP@Work: Мифы и реальности АОП, где развенчиваются некоторые мифы, связанные с использованием АОП, и где содержатся дополнительные ссылки для изучения АОП.

Идея рассказать студентам про АОП у меня возникла тогда, когда я решил к курсовому проекту по предмету «Технологии проектирования программных систем» добавить контейнер Spring Framework, чтобы он создавал все необходимые сервисы, связывал их между собой, а также управлял транзакциями и работой с базой данных. Управление транзакциями происходит декларативно с помощью Java аннотаций над методами или классами. А вот непосредственно код, связанный с транзакциями, находится в аспектах, которые подключаются к проекту. На лекции я старался объяснить, что нам дает использование АОП, а также показать основные способы применения AspectJ.




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


5 comments:

Art said...

Юрий, после прочтения данной темы, решил внедрить в свой проект AspectJ, но возникла проблема, в Eclipse он никак не хочется вешаться на стандартный Java проект, не подскажете ли вы как можно провести интеграцию?

Yuriy said...

Я использовал плагин AJDT. Потом просто добавить поддержку AspectJ в проект. Если же проект собираете антом, тогда надо добавить в проект aspectjtools.jar, подключить в ант цели и компилировать проект аспектовским компилятором.

Art said...

Спасибо, получилось.

Anonymous said...

Спасибо!!!

Unknown said...

Юрий добрый день, хочу добавить логирование запросов и ответов при тестировании REST Web Service.
У меня есть класс Main внутри него отправляется запрос и получается ответ (все делается статическими методами одного фреймворка) мне нужно ловить выполнение этих методов и логировать их параметры ( в идеале), но чтобы понять что аспектом хоть что то ловиться я пока хочу вывести сообщение в консоль, но ничего не выходит, что я делаю не так ?
Исходный код метода main:

public static void main(String[] args) {
ResponseSpecBuilder builder = new ResponseSpecBuilder();
builder.expectContentType("application/json");
builder.expectStatusLine("HTTP/1.1 200 OK");

//нужно словить это builder.expectBody("totalResultsCount", CoreMatchers.is(0));
ResponseSpecification responseSpec = builder.build();
Response response = RestAssured.expect().spec(responseSpec).get("http://ws.geonames.org/searchJSON");
System.out.println(response.getStatusLine());
System.out.println(response.getHeaders().toString() +"\n");
System.out.println(response.body().prettyPrint());
RequestSpecification r = RestAssured.expect().spec(responseSpec).request();
}


pointcut mes(): execution(static * *.*(..)); - ловит все внутри метода main включая сам main.

pointcut expect(): execution(* com.jayway.restassured.builder.ResponseSpecBuilder.expectBody(..)); - не ловит ничего

pointcut expect(): call(* com.jayway.restassured.builder.ResponseSpecBuilder.expectBody(..)); - так же ничего не ловит

Адвайс
after(): expect() {
System.out.println("builder");
}

помогите разобраться в чем проблема, спасибо