2012-10-24

Spring AOP или AspectJ: в чем же все таки разница?

Привет всем адептам Spring!
Продолжаем отвечать на популярные вопросы о фреймворке.

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

Начнем с определения понятий.  
AOP - аспектно-ориентированное программирование, парадигма предназначенная для того, чтобы отделить, так называемую, cross-cutting функциональность от основного кода приложения, сгруппировав ее в одном месте. Основными составными частями AOP являются:
  1.  Join point  - место где мы вызываем наш специфический код.
  2.  Pointcut - совокупность join point.
  3.  Advice - собственно код нашей функциональности, который мы будем вызывать.
  4.  Aspect - совокупность второго и третьего.

Далее, рассмотрим, что такое Spring AOP.
Это реализация AOP, специально разработанная для использования Spring. Она оперирует только только с method execution join points. В случае работы с интерфейсными типами, Spring AOP использует J2SE dynamic proxies, в противном случае с классами используется библиотека CGLIB. Документация тут.

Идем дальше - стили AOP.
@AspectJ это стиль объявления аспектов, как Java классов, с использованием аннотаций, разработанный проектом AspectJ. Spring поддерживает эти аннотации (объявление аспекта, декларация pointcut) и автоматически проксирует те бины, к которым будут применены аспекты. Прошу заметить что тут по прежнему используется ТОЛЬКО механизмы Spring AOP и не присутствуют зависимости от AspectJ compiler и weaver.
Spring имеет namespace для работы с AOP. Для начала работы (чтоб Spring сам искал в контексте компоненты, которые являются аспектами, то есть имеют @Aspect) требуется объявить:
Пример из нашего репозитория тут.
Документация тут.


Аналогичным образом можно использовать исключительно XML контекст для объявления и работы с аспектами. С использованием того же namespace, что и для @AspectJ style. Документауия ут.

Теперь немного больше про AspectJ

AspectJ является имплементацией AOP для Java. Это самостоятельная технология не имеющая отношения к Spring кроме того, что фреймворк ее удачно использует. Как понятно из вышесказанного - можно использовать AOP на основе AspectJ без Spring. Она достаточно нетривиальна (как обычно Spring сделал ее для нас проще). В случае использования AspectJ вы можете либо использовать аннотации @AspectJ-style, либо язык AspectJ. Кто знаком со Spring Roo, тот обращал внимание, что там используются  отдельные файлы ( .aj ) для хранения аспектов - это пример использования языка AspectJ.
 Подробнее об AspectJ тут.

Теперь по выбору подхода в каждом конкретном случае. 
Вы можете использовать Spring AOP как полностью XML конфигурацию, @AspectJ, с использованием языка AspectJ. Кроме того у вас есть возможность использовать непосредственно AspectJ (который тоже имеет варианты использования). В документации все очень неплохо описано. Рекомендую почитать тут. Если резюмировать для тех, кто не прошел по ссылке - чем проще  - тем лучше. Если вам достаточно возможностей Spring AOP (ограничен poincut при вызове метода), используйте его. Причем dynamic proxies, конечно же, легковесней использования CGLIB. Аннотационный подход предпочтительней в любом из случаев.

 Чего я не нашел в документации, так это подробного описание использования AspectJ ВМЕСТО Spring AOP. Документация ограничивается использованием @Configurable для расширения Spring контекста на бины ВНЕ контейнера. При этом используется Load Time Weaving (LTW). Кстати, пример использования этого подхода для интеграции Spring c Vaadin тут.

А вообще, тема интересная, так, что это только начало. Дальше  - больше: использование @Cachable, Spring Data Graph, Spring for Andoid.
Всегда ваши me & eugene.


2012-10-13

Списки полезных ссылок

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

2012-10-06

Spring MVC REST + Spring Android

Приветствую читателей!
В дополнение к нашей презентации о новинках Spring MVC 3.1 мы решили добавить в наш репозиторий приложение на Spring Android в качестве клиента для REST сервиса, который мы показывали. Большое спасибо Толику Каверину за помощь в разработке клиента.

2012-10-05

Spring Security: Защити свое приложение

Приветствую всех любителей Spring :)

Сразу прошу простить за долгий перерыв. Причиной тому и наши гастроли во Львовe и подготовка выступления в Киеве, а также куча всякой мелочи в виде необходимости зарабатывать на жизнь :) Есть интересный проекты - напишите мне.

В данной статье я хотел бы показать пример настройки Spring Security для веб проекта. Делать то, чего 100500 раз понаписано в интернетах я не хотел, моя цель была сделать что-то полезное и информативное. Поэтому я попробовал сделать пример не таким тривиальным как в интернетах, кроме того, код как обычно в нашем проекте на GitHub.

Ну как обычно это работает примерно как магия раз-два-три:

Раз. Фильтры web.xml:

Для ограничение доступа к своим страницам SS использует servlet filter (рекомендую почитать как это работает, если кто запамятовал, чтоб понимать что происходит дальше. А вообще вот и реализация Chain of Responsibility, которую так часто любят спрашивать на собесах).

Два. Контекст. Я предлагаю создать отдельный контекст (и включить его потом в application-context). В этом же контексте лучше всего использовать security namespace:

На первой части останавливаться не буду. Так я подключаю нужные мне компоненты и отфильтровываю  ненужные.
Начнем в тега http. Документация говорит что минимальная необходимая функциональность это использование атрибута auto-config, который является шорткатом (см. документацию). В данном случае я прошу SS сгенерировать мне форму логина и форму логаута, а также описываю поведение при попадании на определенный url pattern (как работает описано тут).
Для формы существует масса дополнительных атрибутов с которыми я рекомендую ознакомиться. 
Наличие же тега authentication-manager говорит о том как я буду осуществлять аутентификацию. В моем случае я делегирую это userService, который я имплементировал как компонент. Также я использую хеширование пароля с использованием sha, а также salt в виде username (в моем случае как мы увидим из UserService это email). Пользователей с их правами доступа можно хранить прямо в контексте, как показано в большинстве тривиальных примеров.
Для упрощения я мог бы использовать  стандартную схему БД и вместо моего сервиса передавать Data Source этой базы.

Детали: Кастомная форма логина/логаута
Для использование своей собственной формы, вместо сгенерированной, вам необходимо указать ее в теге login-form. Кроме того вам придется использовать именование полей формы по умолчанию (как тут). Аналогично с формой logout. По умолчанию она logout осуществляется по адресу /j_spring-security_logout

Детали: Роли пользователей
В теге intercept-url я могу указать роль пользователя. Таким образом я могу сделать иерархическую структуру безопасности.

Детали: Интеграция с LDAP
Этому посвящена целая глава мануала.


Три (как видно из прошлого пункта шаг не обязательный) Имплементация UserDetailsService:

  Это тянет за собой создание entity, ее добавления к persistence entities, создание Dao (да простят мне читатели использование олдскульного нетипизированного criteria API, обещаю поправить  на Hibernate 4 style), а также создание адаптера, чтоб возвращать объект имплементирующий UserDetails.

Детали: Создание пользователей
При хранении пароль в виде хеша не задудьте что вам необходимо после регистрации захешировать пароль с сохранить его в базе.


Про добавление зависимостей в maven писать не буду. Кому надо тот посмотрит в коде проекта, а кто не использует maven тому будет неинтересно.

Из того, что не добавил, но стоит сделать это Service Layer Security.  Мощный механизм и простой как раз-два-три.

 Рекомендованная литература: Spring Security documentation, Spring Security Tutorial

Дальше опять про AOP, Spring Shell, @Cachable, Spring Data для Neo4j и еще немного про Conversion & Formatting Service.
Всего всего - ваши me & eugene. Stay tuned.

2012-10-04

Выступление в Киеве

Приветствую читателей!
В конце месяца мы с Женей хотели бы повторить наш опыт и провести воркшоп Spring By Example в Киеве. Сейчас идет точное уточнение дат и принимающей компании. Если у Вас есть какие-либо пожелания/предложения  - напишите мне.