Предыстория
Фреймворк Spring является одним из наиболее часто используемых при написании Java-приложений.
В ходе его использования все же иногда хотелось бы более глубокого уровня понимания и знания внутренних его механизмов. Поэтому, когда увидел вышедшую на русском языке книгу «Spring in Action» («Spring в действии»), решил, что пришла наконец пора разобраться и погасить этот технический долг.
В процессе чтения возникло желание делать некоторые пометки, чтобы потом, быстро просмотрев их, — без особых затрат времени восстановить картину прочитанного.
Данная статья представляет собой краткий конспект гл.1 данной книги. Если статья покажется удачной — планирую написать аналогичные по остальным главам.
Примечание: это перевод третьего издания книги, в котором рассматривается Spring 3.
Часть 1. Ядро Spring
В предисловии к первой части выделяются две основные особенности фреймворка: внедрение зависимостей (DI=Dependency Injection) и аспектно-ориентированное программирование (AOP=Aspect Oriented Programming).
Указывается, о чем будут главы 1-5 книги:
Гл.1 Вводная, краткий обзор DI и AOP, которые могут помочь ослабить связь между объектами в приложении.
Гл.2 Более детальный рассказ о DI, о том как объявить и связать компоненты посредством xml-конфигурации.
Гл.3 Дополнительные особенности контейнера Spring и расширенные более мощные приемы конфигурирования Spring.
Гл.4 Уменьшение объема xml-конфигурации Spring за счет использования альтернативных non-xml способов конфигурации.
Гл.5 Аспектно-ориентированное программирование в Spring.
Глава 1. Введение в Spring
Цель главы — быстро пробежаться по концепциям и показать на примерах профит использования Spring.
Исторически Spring появился как альтернатива EJB, оттуда же пошло употребление термина «Bean» по аналогии с «JavaBean» у EJB.
Но в отличие от EJB — бины Спринга — это простые POJO-классы, содержащие только методы, нужные для реализации бизнес-логики, тогда как EJB вынуждало реализовывать целый ряд методов для обеспечения существования своих компонентов. Это загрязняло код и понижало его читаемость. Возникал вопрос — фреймворк для нас или наоборот?
1.1 Упрощение разработки приложений
Spring предназначен для упрощения разработки приложений на Java, за счет:
— легковесности и ненасильственности благодаря применению POJO-объектов
пример: POJO-класс сравнивается с аналогичным ejb-шным javabean-ом. Выигрыш в объеме кода у Spring-варианта очевиден
легковесность — в компактности кода, ненасильственность — в ненавязывании нам ненужных интерфейсов, которые надо имплементить.
— слабого связывания посредством внедрения зависимостей и ориентированностью на интерфейсы
пример: xml-файл, в котором описаны 2 бина — бин BraveKnight, которому инжектается в конструктор бин Quest и бин SlayDragonQuest — конфигурация плоская и понятная.
Вводится понятие «контекст». Показывается способ загрузки xml-контекста посредством создания объекта класса ClassPathXmlApplicationContext, которому передают имя xml-файла. Spring сам создает объекты (в нужном порядке) и осуществляет их связывание (wiring). Забегая вперед — скажу: как оказалось — «контекст» в Спринге — это всегда java-класс; в зависимости от того, как он (контекст) сконфигурирован — такой класс и будет загружаться.
Слабое связывание проявляется в том, что конфигурация декларативно описана в xml-файле, а Spring сам занимается разрешением зависимостей. Ориентированность на интерфейсы позволяет легко тестировать созданные классы, инжектая при необходимости в нужные места другие, тестовые бины-обманки (моки/заглушки).
— декларативного программирования через аспекты
Часто в приложении есть функциональность, пронизывающая его насквозь (транзакции, права доступа, логгирование). В данной ситуации реализация такой функциональности может привести к ненужной связанности разных частей приложения, потере гибкости и/или дублированию кода; также бизнес логика может загрязняться не относящимся к ней кодом. Данную проблему хорошо решают подходы аспектно-ориентированного программирования, которое позволяет отделить сквозную функциональность в отдельные компоненты.
Аспекты можно представить как некие обертки компонентов, наделяющие их дополнительными слоями. Компоненты при этом могут и не догадываться о существовании внешних слоев.
Пример: Менестрель, который поет одну песню о рыцаре до его подвига и другую после. Добавив менестреля в качестве поля в класс Рыцарь — получают кривой дизайн, т.к. Рыцарь существует помимо менестреля и знать-то о нем ничего не должен. В итоге от такого подхода отказываются и делают менестреля аспектом: один его метод выполняется до выполнения рыцарем квеста, второй — после. Теперь стало хорошо.
— уменьшения объема типового кода через аспекты и шаблоны
пример: приводится объемный кусок кода по работе с jdbc с кучей catch и т.п. В итоге весь код успешно заменяется использованием jdbcTemplate, который избавляет от написания повторяющегося кода с ловлей исключений
1.2 Понятие контейнера компонентов
Контейнер создает объекты, связывает их и управляет их жизненным циклом.
Указывается о нескольких реализациях контейнера — это могут быть фабрика компонентов (обеспечивает базовую функциональность внедрения зависимостей) либо контекст приложений (основан на фабрике компонентов но обеспечивает доп. функциональность). Указывается на предпочтительность второго варианта как не такого низкоуровневого.
Часто используемые способы создания контекста:
— Загрузка из xml-файла, расположенного в библиотеке классов
— Загрузка из xml-файла в файловой системе
— Загрузка из xml-файла, содержащегося внутри веб-приложения
Жизненный цикл компонента:
1. Создание экземпляра компонента
2. Spring внедряет значения и ссылки на другие компоненты в свойства этого компонента
3. Если компонент реализует интерфейс BeanNameAware, Spring передает идентификатор компонента методу setBeanName()
4. Если компонент реализует интерфейс BeanFactoryAware, Spring вызывает метод setBeanFactory(), передавая ему саму фабрику компонентов
5. Если компонент реализует интерфейс ApplicationContextAware, Spring вызывает метод setApplicationContext(), передавая ему ссылку на вмещающий контекст приложения
6. Если какие-либо из компонентов реализуют интерфейс BeanPostProcessor, Spring вызывает их методы postProcessBeforeInitialization()
7. Если какие-либо из компонентов реализуют интерфейс InitializingBean, Spring вызывает их методы afterPropertiesSet(). Аналогично, если компонент был объявлен с атрибутом init-method, вызывается указанный метод инициализации
8. Если какие-либо из компонентов реализуют интерфейс BeanPostProcessor, Spring вызывает их методы postProcessAfterInitialization()
9. В этот момент компонент готов к использованию приложением и будет сохраняться в контексте приложения, пока он не будет уничтожен
10. Если какие-либо из компонентов реализуют интерфейс DisposableBean, Spring вызывает их методы destroy(). Аналогично, если компонент был объявлен с атрибутом destroy-method, вызывается указанный метод
1.3 Обзор возможностей Spring
Проводится попытка разложить фреймворк на составные части:
— Контейнер Spring, управляющий процессом создания бинов и настройки приложений
— Модуль AOP, обеспечивающий поддержку аспектов
— Доступ к данным и интеграция: инструменты для работы с JDBC, ORM-решениями, сообщениями (JMS)
— MVC с реализацией одноименной парадигмы
— Модуль поддержки тестирования приложений с возможностью использования фиктивных объектов (моков) и интеграционного тестирования
Бегло перечисляются еще десяток специфичных модулей:
— Spring Web Flow для реализации многоэтапных приложений
— Spring Web Services для реализации служб по модели contract-first
— Spring Security для реализации управления безопасностью приложений
— Spring Batch для пакетной обработки данных
— Spring LDAP — для доступа к одноименной службе директорий
и другие
1.4 Что нового в Spring
Приводится перечисление того, что нового появилось в Spring с момента выхода прошлого издания книги.
Учитывая, что данная статья является первой в серии, перечисление новшеств не будет полезным на данном этапе.
Создается впечатление о некоей неудержимой тотальности проникновения Spring в разные аспекты разработки.
1.5 Заключение
Теперь читатель книги имеет поверхностное представление, какими возможностями обладает Spring, созданный для того, чтобы облегчить создание корпоративных приложений на Java.
Звучит приглашение к гл. 2, чтобы узнать, как работает внедрение зависимостей.
Фреймворк Spring является одним из наиболее часто используемых при написании Java-приложений.
В ходе его использования все же иногда хотелось бы более глубокого уровня понимания и знания внутренних его механизмов. Поэтому, когда увидел вышедшую на русском языке книгу «Spring in Action» («Spring в действии»), решил, что пришла наконец пора разобраться и погасить этот технический долг.
В процессе чтения возникло желание делать некоторые пометки, чтобы потом, быстро просмотрев их, — без особых затрат времени восстановить картину прочитанного.
Данная статья представляет собой краткий конспект гл.1 данной книги. Если статья покажется удачной — планирую написать аналогичные по остальным главам.
Примечание: это перевод третьего издания книги, в котором рассматривается Spring 3.
Часть 1. Ядро Spring
В предисловии к первой части выделяются две основные особенности фреймворка: внедрение зависимостей (DI=Dependency Injection) и аспектно-ориентированное программирование (AOP=Aspect Oriented Programming).
Указывается, о чем будут главы 1-5 книги:
Гл.1 Вводная, краткий обзор DI и AOP, которые могут помочь ослабить связь между объектами в приложении.
Гл.2 Более детальный рассказ о DI, о том как объявить и связать компоненты посредством xml-конфигурации.
Гл.3 Дополнительные особенности контейнера Spring и расширенные более мощные приемы конфигурирования Spring.
Гл.4 Уменьшение объема xml-конфигурации Spring за счет использования альтернативных non-xml способов конфигурации.
Гл.5 Аспектно-ориентированное программирование в Spring.
Глава 1. Введение в Spring
Цель главы — быстро пробежаться по концепциям и показать на примерах профит использования Spring.
Исторически Spring появился как альтернатива EJB, оттуда же пошло употребление термина «Bean» по аналогии с «JavaBean» у EJB.
Но в отличие от EJB — бины Спринга — это простые POJO-классы, содержащие только методы, нужные для реализации бизнес-логики, тогда как EJB вынуждало реализовывать целый ряд методов для обеспечения существования своих компонентов. Это загрязняло код и понижало его читаемость. Возникал вопрос — фреймворк для нас или наоборот?
1.1 Упрощение разработки приложений
Spring предназначен для упрощения разработки приложений на Java, за счет:
— легковесности и ненасильственности благодаря применению POJO-объектов
пример: POJO-класс сравнивается с аналогичным ejb-шным javabean-ом. Выигрыш в объеме кода у Spring-варианта очевиден
легковесность — в компактности кода, ненасильственность — в ненавязывании нам ненужных интерфейсов, которые надо имплементить.
— слабого связывания посредством внедрения зависимостей и ориентированностью на интерфейсы
пример: xml-файл, в котором описаны 2 бина — бин BraveKnight, которому инжектается в конструктор бин Quest и бин SlayDragonQuest — конфигурация плоская и понятная.
Вводится понятие «контекст». Показывается способ загрузки xml-контекста посредством создания объекта класса ClassPathXmlApplicationContext, которому передают имя xml-файла. Spring сам создает объекты (в нужном порядке) и осуществляет их связывание (wiring). Забегая вперед — скажу: как оказалось — «контекст» в Спринге — это всегда java-класс; в зависимости от того, как он (контекст) сконфигурирован — такой класс и будет загружаться.
Слабое связывание проявляется в том, что конфигурация декларативно описана в xml-файле, а Spring сам занимается разрешением зависимостей. Ориентированность на интерфейсы позволяет легко тестировать созданные классы, инжектая при необходимости в нужные места другие, тестовые бины-обманки (моки/заглушки).
— декларативного программирования через аспекты
Часто в приложении есть функциональность, пронизывающая его насквозь (транзакции, права доступа, логгирование). В данной ситуации реализация такой функциональности может привести к ненужной связанности разных частей приложения, потере гибкости и/или дублированию кода; также бизнес логика может загрязняться не относящимся к ней кодом. Данную проблему хорошо решают подходы аспектно-ориентированного программирования, которое позволяет отделить сквозную функциональность в отдельные компоненты.
Аспекты можно представить как некие обертки компонентов, наделяющие их дополнительными слоями. Компоненты при этом могут и не догадываться о существовании внешних слоев.
Пример: Менестрель, который поет одну песню о рыцаре до его подвига и другую после. Добавив менестреля в качестве поля в класс Рыцарь — получают кривой дизайн, т.к. Рыцарь существует помимо менестреля и знать-то о нем ничего не должен. В итоге от такого подхода отказываются и делают менестреля аспектом: один его метод выполняется до выполнения рыцарем квеста, второй — после. Теперь стало хорошо.
— уменьшения объема типового кода через аспекты и шаблоны
пример: приводится объемный кусок кода по работе с jdbc с кучей catch и т.п. В итоге весь код успешно заменяется использованием jdbcTemplate, который избавляет от написания повторяющегося кода с ловлей исключений
1.2 Понятие контейнера компонентов
Контейнер создает объекты, связывает их и управляет их жизненным циклом.
Указывается о нескольких реализациях контейнера — это могут быть фабрика компонентов (обеспечивает базовую функциональность внедрения зависимостей) либо контекст приложений (основан на фабрике компонентов но обеспечивает доп. функциональность). Указывается на предпочтительность второго варианта как не такого низкоуровневого.
Часто используемые способы создания контекста:
— Загрузка из xml-файла, расположенного в библиотеке классов
— Загрузка из xml-файла в файловой системе
— Загрузка из xml-файла, содержащегося внутри веб-приложения
Жизненный цикл компонента:
1. Создание экземпляра компонента
2. Spring внедряет значения и ссылки на другие компоненты в свойства этого компонента
3. Если компонент реализует интерфейс BeanNameAware, Spring передает идентификатор компонента методу setBeanName()
4. Если компонент реализует интерфейс BeanFactoryAware, Spring вызывает метод setBeanFactory(), передавая ему саму фабрику компонентов
5. Если компонент реализует интерфейс ApplicationContextAware, Spring вызывает метод setApplicationContext(), передавая ему ссылку на вмещающий контекст приложения
6. Если какие-либо из компонентов реализуют интерфейс BeanPostProcessor, Spring вызывает их методы postProcessBeforeInitialization()
7. Если какие-либо из компонентов реализуют интерфейс InitializingBean, Spring вызывает их методы afterPropertiesSet(). Аналогично, если компонент был объявлен с атрибутом init-method, вызывается указанный метод инициализации
8. Если какие-либо из компонентов реализуют интерфейс BeanPostProcessor, Spring вызывает их методы postProcessAfterInitialization()
9. В этот момент компонент готов к использованию приложением и будет сохраняться в контексте приложения, пока он не будет уничтожен
10. Если какие-либо из компонентов реализуют интерфейс DisposableBean, Spring вызывает их методы destroy(). Аналогично, если компонент был объявлен с атрибутом destroy-method, вызывается указанный метод
1.3 Обзор возможностей Spring
Проводится попытка разложить фреймворк на составные части:
— Контейнер Spring, управляющий процессом создания бинов и настройки приложений
— Модуль AOP, обеспечивающий поддержку аспектов
— Доступ к данным и интеграция: инструменты для работы с JDBC, ORM-решениями, сообщениями (JMS)
— MVC с реализацией одноименной парадигмы
— Модуль поддержки тестирования приложений с возможностью использования фиктивных объектов (моков) и интеграционного тестирования
Бегло перечисляются еще десяток специфичных модулей:
— Spring Web Flow для реализации многоэтапных приложений
— Spring Web Services для реализации служб по модели contract-first
— Spring Security для реализации управления безопасностью приложений
— Spring Batch для пакетной обработки данных
— Spring LDAP — для доступа к одноименной службе директорий
и другие
1.4 Что нового в Spring
Приводится перечисление того, что нового появилось в Spring с момента выхода прошлого издания книги.
Учитывая, что данная статья является первой в серии, перечисление новшеств не будет полезным на данном этапе.
Создается впечатление о некоей неудержимой тотальности проникновения Spring в разные аспекты разработки.
1.5 Заключение
Теперь читатель книги имеет поверхностное представление, какими возможностями обладает Spring, созданный для того, чтобы облегчить создание корпоративных приложений на Java.
Звучит приглашение к гл. 2, чтобы узнать, как работает внедрение зависимостей.
js605451
Поставил минус — не вижу пользы от таких постов: для начинающих — слишком поверхностно (и вообще «ни о чём»), им как раз лучше всю книгу прочитать (да ещё и пару раз), для неначинающих не проблема погуглить или просто пойти почитать документацию, а совсем неначинающие и так всё это знают. Такие заметки, наверное, лучше постить в свой блог. Тем более если вы планируете больше одного поста.