Spring

max аватар

  SpringJUnit4ClassRunner type mismatch

76
Находится в разделах:

Решил попробовать SpringJUnit4ClassRunner в тандеме с JUnit для юнит-тестирования, который поставляется в spring-test модуле.

Описание артифакта для мавена:

 

Сделал тестовый класс по туториалу.

max аватар

  Spring. Теги на форме / Form Tags

98
Находится в разделах:

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

Имеется форма регистрации пользователя:

max аватар

  Spring: Контроллеры, основанные на аннотациях / Annotation Controller. Пример

89
Находится в разделах:

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

При использовании контроллеров, базирующихся на аннотациях, нет необходимости наследоваться от специальных классов или реализовывать какие-то интерфейсы. Единственное, что необходимо сделать - это превратить простой java класс в Spring контроллер с помощью аннотации @Controller.

Рассмотрим листинг описания класса UserController:

 

info picture

Аннотация @Controller используется для магического превращения любого java класса в класс контроллера.

Аннотация @RequestMapping используется для маппинга веб запроса "/userRegistration.htm" на класс UsserController.

Аннотация @SessionAttributes используется для сохранения объекта модели в сессии. В нашем случае, объектом модели выступает user.

max аватар

  Spring SimpleFormController. Пример

88
Находится в разделах:

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

max аватар

  Пример Spring MVC

94
Находится в разделах:

Spring MVC - отличный помощник при построении гибких и слабо связанных веб-приложений. Шаблон проектирования MVC (Model-View-Controller) помогает в разделении бизнес-логики, презентационной логики и логики навигации. Модели ответственны за инкапсулирование данных приложения. Представления генерируют ответ на запрос пользователя с использованием объекта модели. Контроллеры ответственны за получение запроса от пользователя и вызов сервисов на стороне веб-сервера. 

Вот как выглядит запрос в Spring MVC Framework.

spring mvc

Когда запрос посылается в Sping MVC Framework, происходит следующая цепочка событий. 

  • Сперва DispatcherServlet получает запрос
  • DispatcherServlet консультируется с HandlerMapping и вызывает Controller, ассоциированный с этим запросом.
  • Controller обрабатывает запрос посредством вызова соответствующих методов сервиа и возвращает ModelAndView объект в DispatcherServlet. Объект ModelAndView содержит модель данных и имя представления. 
  • DispatcherServlet отсылает имя отображения в ViewResolver для поиска актуального представления для вызова.
  • Теперь DispatcherServlet передаст объект модели в представление (View) и сгенерирует результат.
  • View с помощью модели данных отрендерит результат и отошлет его обратно пользователю.
Для понимания работы Spring MVC Framework мы создадим простой пример hello world с использованием Eclipse
Для демонстрации необходимо иметь Eclipse 3.4 или выше, Spring IDE plugin, Tomcat 6 и Spring 3.
max аватар

  Spring. Внедрение через конструктор / Constructor injection

93
Находится в разделах:

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

Предположим, что имеется класс User.

Класс User имеет три атрибута - name, age, country. Все три атрибута устанавливаются через конструктор. Метод toString() переопределен для отображения объекта пользователя.

Конфигурационный файл beans.xml используется для настройки бинов в контейнере Spring IoC

max аватар

  Spring. Внедрение через сеттер / Setter injection

95
Находится в разделах:

В данном примере рассмотрим процесс установки свойств бина с использованием внедрения через сеттер. 

Предположим, у нас есть класс User.

max аватар

  Настройка Eclipse для работы со Spring IDE + Hello World Spring Application

93
Находится в разделах:

Spring IDE - это плагин для эклипса, помогающий в разработке приложений с использованием Spring. Сперва рассмотрим, как установить Spring IDE, а затем как создать первый проект на Spring.

Для установки плагина необходимо выбрать в меню Help->Software Updates.

spring+eclipse step 1

Нажмите на кнопке "Add Site" и введите адрес "http://springide.org/updatesite" в поле Location.

max аватар

  Spring. Как это работает? Часть 3

95
Находится в разделах:

Продолжение статьи Spring. Как это работает? Часть 2: Создание бинов через вызов конструктора

 

Определение ссылок на бины / Specifying Bean References

Бины, из которых состоит приложение, зачастую нуждаются во взаимодействии друг с другом. Чтобы обеспечить взаимодействие бинов, необходимо задать связи между ними в конфигурационном файле. 

Решение

В конфигурационном файле можно задать ссылку на бин для свойства бина или аргумента конструктора с использованием элемента <ref>. Это так же просто, как и задание значений через элемент <value>. Можно также задать объявление бина в свойстве или аргументе конструктора в виде вложенного бина. 

Как это работает

Прием строкового значения в виде префикса для генератора последовательностей не очень удобно для последующих улучшений продукта. Было бы лучше, если бы генерация префикса могла быть настроена определенной логикой. Создадим интерфейс PrefixGenerator для определения операции генерации префикса.

max аватар

  Spring. Как это работает? Часть 2: Создание бинов через вызов конструктора

95
Находится в разделах:

Продолжение статьи Spring. Как это работает. Часть 1

 

Создание бинов через вызов конструктора

Проблема

Необходимо создать бин в IoC контейнере Spring через вызов его конструктора, наиболее распространенного пути создания бинов. Эквивалентом является использование оператора new для создания объекта в Java. 

Решение

Когда мы задаем атрибут class для бина, мы тем самым просим контейнер создать объект бина через вызов конструктора.

Как это работает

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

max аватар

  Spring. Как это работает? Часть 1

93
Находится в разделах:

Создание экземпляра ApplicationContext

ApplicationContext - это всего лишь интерфейс. А, как мы все знаем, создать объект можно только с реализации, а не с интерфейса. Реализация ClassPathXmlApplicationContext создает контекст через загрузку конфигурации из XML файла, который находится в класспасе (classpath). Можно также задать множество конфигурационных файлов для него.

Кроме ClassPathXmlApplicationContext, Spring предоставляет еще множество реализаций. FileSystemXmlApplicationContext используется для загрузки конфигурационных файлов из файловой системы или из URL, а XmlWebApplicationContext и  XmlPortletApplicationContext могут быть использованы только в веб-приложениях или порталах.

Получение бинов из IoC контейнера

Для того, чтобы получить объявленный бин из фабрики бинов или контекста приложения, достаточно вызвать метод getBean() и передать ему в качестве параметра уникальное имя бина. Поскольку возвращаемый тип объекта - java.lang.Object,  необходимо сделать приведение типов перед использованием.

max аватар

  Один день из жизни J2EE разработчика

103
Находится в разделах:

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

Алекс приступает к работе, открывает свою любимую визуальную среду разработки и начинает набивать код для первого компонента, CustomerManager.  В мире EJB для того, чтобы разработать этот компонент, сперва понадобиться написать несколько классов - "домашний" (home) интерфейс, локальный интерфейс (local interface) ну и сам бин (bean).  В дополнение ко всему, необходимо будет создать дескриптор развертывания (deployment descriptor) для бина. 

 

Заметив тот факт, что создание каждого из этих файлов отнимает много времени и усилий, Алекс внедряет XDoclet  в свой проект. XDoclet - утилита для генерации кода, которая может генерировать все необходимые EJB файлы из одного исходного файла. Хотя это и добавляет дополнительный шаг в цикл разработки, его жизнь как кодера теперь значительно упростилась.  XDoclet теперь делает за него большую часть "грязной" работы и Алекс может сосредоточиться на главной своей проблеме - что в действительности должен делать компонент CustomerManager. Он переходит к своему первому методу, getPreferredCustomer(). Существует определенный набор бизнес правил, определяющих работу с заказчиком и Алекс старательно переносит их в свой бин. 

 

Желая подтвердить тот факт, что его логика работает корректно, он теперь хочет написать несколько тестов для валидации его кода. И тут к нему доходит: код, который он собирается тестировать, должен выполняться внутри контейнера. Его тесты также должны выполняться в контейнере. Алекс по-быстрому пишет сервлет, это позволит ему выполнять его тесты в одном и том же контейнере, что и его EJB. Проблема решена!

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

Во время ожидания запуска контейнера, Алекс думает: "Почему я использую EJB  в первую очередь?". Ответ, конечно, состоит в том, что сервисы предоставляют такой подход. Но Алекс не использует entity beans, следовательно ему не нужно будет использовать persistence. Также он не использует удаленные сервисы или сервисы безопасности. В реальности, единственный EJB сервис, который собирается использовать Алекс - это управление транзакциями.  Это наводит его на мысль, а нет ли более легкого пути?

max аватар

  Spring. Базовое замещение методов при method injection

130
Находится в разделах:

Вы любите выступления иллюзионистов? Иллюзионисты делают невозможные вещи возможными одним легким движением руки. Один из интересных трюков - это трюк, в котором иллюзионист кладет своего ассистента в коробку, крутит ее вокруг своей оси, произносит волшебные слова. Затем коробка открывается, а оттуда вылазит тигр.

И так, создадим класс Magician:

max аватар

  Spring. Внедрение методов (Method injection)

118
Находится в разделах:

В Dependency Injection существует две базовые формы. Внедрение конструктора (constructor injection) позволяет конфигурировать бины, передавая значения в конструкторы бина. В то время, как сеттерное внедрение (setter injection) позволяет конфигурировать бины, передавая значения через методы сеттеров.

Но сейчас не об этом. Рассмотрим необычную форму Dependency Injection, которая называется внедрение метода (method injection). Используя внедрения через сеттеры и конструкторы, мы внедряем значения в свойства бина. Но внедрение метода очень сильно отличается, поскольку позволяет внедрять целые определения методов в бин.

Некоторые языки, такие как Ruby, позволяют добавлять новые методы в любой класс во время выполнения, без изменения определения класса. Но это все Ruby - java не такая гибкая. Тем не мене, Spring предлагает Java разработчикам внедрение методов для того, чтобы разрешить внедрение методов во время выполнения в java классы. 

max аватар

  Spring. Работая с application context

124
Находится в разделах:

Фабрика бинов хороша для простых приложений, но для того, чтобы получить всю мощь Spring Framework, Вы, возможно, захотите загрузить бины вашего приложения с использованием более расширенного контейнера - application context.

Поверхностно, ApplicationContext - почти то же, что и BeanFactory. Оба загружают определения бинов, связывают их вместе. Но ApplicationContext предлагает нечто большее:

  • Контекст приложения предоставляет распознавание текстовых сообщений, включая поддержку интернализации этих сообщений (i18n).
  • Контекст приложения предоставляет обобщенный вариант загрузки файловых ресурсов, таких как изображения.
  • Контекст приложения может  публиковать события в бины, которые зарегистрированы как прослушиватели (listeners).
Из-за преимуществ на фабрикой бинов, ApplicationContext является более предпочтительным почти во всех приложениях. 
Среди многих реализаций ApplicationContext три из них используются довольно часто:
max аватар

  Spring. Введение в BeanFactory

127
Находится в разделах:

Как видно из названия, фабрика бинов - это ни что иное, как реализация шаблона проектирования Factory. Это класс, в чьи обязанности входит создание и уничтожение бинов. Однако, в отличие от многих реализаций паттерна Factory, который обычно выдает один тип объекта, фабрика бинов - это фабрика общего назначения, предназначенная для создания и уничтожения множества типов бинов. Предназначение бинов  немного шире, чем просто создание и доставка объектов приложения. Поскольку фабрика бинов знает многое об объекта внутри приложения, она способна создавать ассоциации между взаимодействующими объектами.  Это снимает бремя  конфигурации бина из самого себя и из бина клиента.  В результате, когда фабрика бинов выдает объекты, эти объекты полностью сконфигурированы и осведомлены об объектах, с которыми они сотрудничают и готовы к использованию. Более того, фабрика бинов также принимает участие в жизненном цикле бина,  делая вызовы определенных методов инициализации и деструкции, если эти методы определены.

В Spring определены несколько реализаций BeanFactory. Но наиболее часто используется org.springframework.beans.factory.xml.XmlBeanFactory, которая загружает бины, основанные на определениях, содержащихся в xml файле. 

Для создания XmlBeanFactory, необходимо передать объект org.springframework.core.io.Resource в конструктор. Объект Reousrce предоставит фабрике  XML. Spring поставляется  с подборкой реализаций Resource. Например, следующий сниппет использует FileSystemResource для создания XmlBeanFactory, чьи определения бина читаются из XML файла:

max аватар

  Spring. Содержание ваших бинов

124
Находится в разделах:

В приложениях, основанных на Spring, все объекты приложения живут внутри контейнера Spring. Контейнер создаст объекты, свяжет их вместе, настроит их и будет управлять полным жизненным циклом от колыбели до могилы (или от new до finalize()). 

Контейнер - это ядро Spring Framework. Контейнер использует dependency injection (DI) для управления компонентами приложения. Это включает в себя создание ассоциаций между взаимодействующими компонентами. Таким образом, эти компоненты более "прозрачны" и более просты в понимании, поддержке и тестировании.

Не существует одного Spring контейнера. Spring поставляется с несколькими реализациями контейнера, которые могут быть разделены на два типа. Фабрики бинов (определенные интерфейсом org.springframework.beans.factory.BeanFactory) , которые являются простейшими контейнерами, предоставляющими базовую поддержку DI.  Контексты приложения (определенные в интерфейсе org.springframework.context.ApplicationContext) создают понятие фабрики бинов, предоставляя сервисы приложения, такие как возможность вытягивать текстовые свойства из файлов свойств и возможность публиковать события приложения для заинтересованных листенеров.

spring container



max аватар

  Spring. Аналогии

111
Находится в разделах:

Вы когда-нибудь оставались после просмотра фильма, когда идут титры? Это невероятно, сколько разных людей необходимо для того, чтобы сделать фильм. Есть очевидные участники: актеры, сценаристы, продюссеры и директора. Есть и не такие уж очевидные участники: музыканты, люди, которые занимаются спецэффектами и художники.  И это не упоминая гримеров, звукорежиссеров, костюмеров, ассистентов и т.д. 

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

Разработка больших программных продуктов мало чем отличается. Любое нетривиальное приложение, сделанное из нескольких объектов, которые должны работать вместе для соответствия какому-то бизнес плану. Эти объекты должны знать друг друга и должны взаимодействовать друг с другом для успешного выполнения работы.  В Spring объекты не отвечают за поиск или создания других объектов, которые необходимы им для работы. Вместо этого, они получают ссылки на объекты, с которыми им необходимо взаимодействовать. Например,  компонент менеджера заказов в онлайн-магазине может нуждаться в авторизаторе кредитных карточек.  

Процедура создания этих ассоциаций между объектами преложения - ядро dependency injection (DI) и общеизвестно как wiring.

max аватар

  Spring. AOP в действии

126
Находится в разделах:

Предположим, что вы хорошо проявили себя с предыдущим заданием. И теперь заказчики пришли к вам с новым заданием. В этом задании, менестрель  (поэт-музыкант из средневековья, сопровождавший рыцарей и воспевавших их действия) должен сопровождать каждого рыцаря, воспевая все его поступки и действия в песнях. Хм... менестрель, который поет о рыцаре? Ничего сложного. Создадим класс Minstrel:

Для поддержания стиля мышления dependency injection, мы изменяем класс KnightOfTheRoundTable для получения объекта Minstrel:

Все должно работать. Хотя стоп... есть небольшая проблемка. Каждый рыцарь должен остановиться и сказать менестрелю, чтобы тот пел песню перед тем, как рыцарь сможет продолжить свой квест. Затем, после квеста, рыцарь должен помнить о том, чтобы сказать менестрелю, чтобы тот продолжил петь. Сам факт того, что рыцарь должен помнить о том, чтобы остановиться и сказать менестрелю что делать, отвлекает рыцаря. 

В идеале, менестрель должен проявлять больше инициативы и автоматически петь песни без предупреждения. Рыцарь не должен знать (или даже заботиться) о том, что его действия записываются в песню. После всего, вы не должны допустить, чтобы ваш рыцарь опоздал на квесты из-за ленивого менестреля.

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

max аватар

  Spring Dependency Injection в действии

124
Находится в разделах:

Предположим, что Ваша компания провела маркетинговые исследования и в результате экспертного анализа пришли к выводу, что вашему заказчику в действительности необходим рыцарь. Да, java класс, который представляет рыцаря. После анализа их требований, вы поняли, что они в действительности хотят от вас реализации класса, который представляет Артура, рыцаря круглого стала, который собирается в походы за поиском Святого Грааля.

Да, это странный запрос, но вы ведь уже привыкли к странным запросам маркетингового тима. Поэтому Вы, без доли сомнения, открываете свой любимый IDE и вбиваете класс.

В этом листинге, имя рыцарю присваивается как параметр конструктора. Его конструктор устанавливает поход рыцаря через создание объекта HolyGrailQuest. Реализация HolyGrailQuest тривиальна:

Глубоко удовлетворенные своей работой, вы с гордостью комитите код в систему версийности кода. Вы хотите показать его маркетинговой команде, но глубоко убеждены, что чего-то не хватает . Вы не написали ни одного юнит-теста.

 

Тестирования рыцаря

Юнит-тестирование - важная часть разработки.