my.life.logging.Blog

Конфигурация связки «Spring - Hibernate» без использования XML

В продолжение поста про конфигурацию Spring MVC без использования XML, решил рассказать о том, как, опять же не написав ни строчки XML, подключить к приложению Spring такой ORM-фреймворк, как Hibernate. И хотя программная конфигурация связки “Spring – Hibernate” не выглядит настолько же красивой, как и программная конфигурация Spring MVC – знать о подобной возможности уж точно не помешает.

Конфигурация приложения Spring MVC (почти) без использования XML

Доброе время суток, господа джависты!

Думаю, я не буду далек от истины, если скажу, что XML сейчас – это главный бич нашего с вами программистского Java поколения!

Что уж там говорить, когда все эти открывающие и закрывающие XML-теги, спецсимволы и “verbosity” даже больше, чем у Java, могут любого, даже самого уравновешенного кодера, довести до белого каления. А отсутствие какой бы-то ни было полноты по Тьюрингу и возможности отладки в XML часто заставляет плакать от безысходности при написании даже самых простых скриптов Ant. А в скольких разработческих стрессах, испорченном настроении и отсутствии иммунитета виноват проклятый XML! И я даже слышал об одном бедном программисте, который чуть было не повесился после того, как ему поручили написать код трансформации документа XML в документ XHTML с помощью XSLT-преобразования, с обязательной проверкой входного документа при помощи XSD-схемы!..

А что выбираешь ты?

Но время проходит, тучи рассеиваются…

Удаление старых веток в Git

“Ветвиться, ветвиться и еще раз ветвиться!” – как завещал великий Линус Торвальдс. Ветвления – вот уж в чем действительно вся суть программирования. Ведь даже цикл на примитивном уровне реализуется с помощью ветвлений, не говоря уже о бинарных деревьях и прочих ветвистых структурах данных.

Так что помни, мой юный падован: применяя Git, всегда следуй максиме “Рано фиксируй, часто ответвляй”, и будет тебе счастье!..

Но если ты будешь неукоснительно выполнять заветы Линусича и компании, то очень скоро столкнешься с ситуацией, когда количество строк, выдаваемых командой git branch (не говоря уже о git branch -a) для твоего репозитория, не будет умещаться даже на нескольких экранах терминала. Мда, чтобы найти необходимую ветку среди всего этого безобразия, придется серьезно потрудиться. Или есть другой вариант – избавиться от ненужных веток. Но, согласись, удалять каждую неактуальную ветку по-отдельности – не самое благодарное занятие для разработчика, находящегося в жестких сроках проекта.

Так нельзя ли, подумал я, этот процесс каким-нибудь образом автоматизировать?

Словарь инженера по производительности

Инженер по производительности

Выписал из книги “The Well-Grounded Java Developer” перечень метрик, наиболее часто используемых в процессе тюнинга производительности приложения. Представленные здесь метрики – это базовая статистика системы, другие (иногда все же применяемые во время настройки производительности) – менее важны. Думаю, информация будет полезна при чтении статей, посвященных, например, опитимизации производительности JVM.

Создание портлета для Liferay с помощью Wicket. Часть 4. Если используется Spring Framework.

Данное руководство детально описывает процесс создания портлета для Liferay портала cредствами фреймворка Wicket.

Все части руководства:

  1. Портлетный проект для Liferay портала
  2. Конфигурация Wicket-портлета, или web.xml, portlet.xml и т.д., и т.п.
  3. Разработка функциональности Wicket-портлета
  4. Если используется Spring Framework

Исходный код разрабатываемого примера доступен на GitHub.


“Весеннее” достижение

Если ты, уважаемый читатель, хорошо знаком с программистским фольклором и до сих пор наивно полагаешь, что Java – это “язык индустриальной эпохи”, и в его экосистеме не осталось такого места, которое не было бы загрязнено выбросами “фабрик”, то боюсь, конечно, тебя разочаровывать, но, по всей видимости, ты безнадежно отстал от жизни. Ибо с середины 2000х годов Java – это все-таки скорее и чаще Spring Framework, “Dependency Injection” и все, что с этим связано.

Одной из частей рассмативаемого нами в этом руководстве фреймворка Wicket является модуль, который занимается его интеграцией со Spring. Таким образом, если требуется применить IoC, вынести какую-либо конфигурацию в XML, настроить авторизацию с помощью Spring Security, воспользоваться AOP или, страшно сказать, задействовать в проекте мессаджинг с помощью JMS – Wicket не станет помехой для реализации всех этих вещей с помощью Spring Framework. На самом деле, Wicket просто выступит в качестве представления для всей остальной логики приложения, большая часть которой может быть написана как раз с использованием Spring.

Согласись, было бы неплохо, если бы всеми инструментами Spring мы могли бы воспользоваться и при разработке портлета на Wicket?

Создание портлета для Liferay с помощью Wicket. Часть 3. Разработка функциональности портлета.

Данное руководство детально описывает процесс создания портлета для Liferay портала cредствами фреймворка Wicket.

Все части руководства:

  1. Портлетный проект для Liferay портала
  2. Конфигурация Wicket-портлета, или web.xml, portlet.xml и т.д., и т.п.
  3. Разработка функциональности Wicket-портлета
  4. Если используется Spring Framework

Исходный код разрабатываемого примера доступен на GitHub.


Три портлетных режима

Согласно портлетной спецификации, портлет может функционировать в трех различных режимах:

  • режиме просмотра (view mode),
  • режиме редактирования (edit mode),
  • режиме справки (help mode).

Несмотря на всю негибкость подобного технического решения (ведь вполне справедливыми будут вопросы: “Разве нельзя найти лучшего места для документации, чем режим справки портлета?”, “А почему нельзя задавать параметры всех портлетов централизовано из одного места?”), мне лично идея изменения настроек портлета в режиме редактирования понравилась. Быть может, потому что подобная функциональность очень хорошо подходила для той задачи, которую мне пришлось решать. И вообще если рассматривать создание какой-нибудь CMS, то для настройки отдельных функциональных блоков на странице возможности их перехода в режим редактирования вполне достаточно.

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

Создание портлета для Liferay с помощью Wicket. Часть 2. Конфигурация Wicket-портлета, или web.xml, portlet.xml и т.д., и т.п.

Данное руководство детально описывает процесс создания портлета для Liferay портала cредствами фреймворка Wicket.

Все части руководства:

  1. Портлетный проект для Liferay портала
  2. Конфигурация Wicket-портлета, или web.xml, portlet.xml и т.д., и т.п.
  3. Разработка функциональности Wicket-портлета
  4. Если используется Spring Framework

Исходный код разрабатываемого примера доступен на GitHub.


Изменяем файл web.xml

В моем случае SDK не создал файл web.xml в проекте портлета, хотя для Wicket он нужен. Не проблема - создадим его сами.

Создание портлета для Liferay с помощью Wicket. Часть 1. Портлетный проект для Liferay портала

Данное руководство детально описывает процесс создания портлета для Liferay портала cредствами фреймворка Wicket.

Все части руководства:

  1. Портлетный проект для Liferay портала
  2. Конфигурация Wicket-портлета, или web.xml, portlet.xml и т.д., и т.п.
  3. Разработка функциональности Wicket-портлета
  4. Если используется Spring Framework

Исходный код разрабатываемого примера доступен на GitHub.


Приветствую тебя, уважаемый пользователь фреймворка Wicket!

Насколько я понимаю, у тебя возникла насущная необходимость разработать один-два непритязательных портлета для Liferay портала, и именно поэтому ты решил почитать это руководство? Если так, то я постараюсь показать тебе в деталях, каким образом можно создать небольшой портлет с помощью Wicket.

Использование в Wicket компонентов, написанных на JavaScript

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

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

Почему нужно минимизировать память Web-приложения

Все, что изложено ниже, является вольным пересказом некоторых интересных примечаний из книги M. Dashorst, E. Hillenius “Wicket in Action”.

Есть одно важное отличие в плане разработки между традиционным “тонким” клиентом и современным полнофункциональным web-приложением, о котором не так часто говорят. Это отличие - в том, что при разработке web-приложения нужно стремиться к минимуму используемой им памяти.

Представим для начала, что для работы с сервером вам требуется написать просто desktop-приложение. Будете ли вы в первую очередь беспокоиться о том, сколько памяти оно будет требовать для своей работы? Учитывая, что дни компьютеров с 640 KB на борту давно позади, и мы живем в те времена, когда для того, чтобы купить несколько тысяч лишних MB оперативы, не нужно копить несколько лет, работая на трех работах, даже если ваше приложение будет требовать для работы 10-20 MB памяти, это значит лишь, что вам просто не о чем волноваться. Не так уж и плохо, учитывая, что iTunes может запросто скушать 145 MB.

Но если вы пишете web-приложение, которым будут пользоваться 100 человек одновременно, то тогда требования к памяти сервера взлетают сразу же до 1 GB! А что будет, если ваше приложение станет популярным и о нем узнают тысячи человек? В таком случае у вас будет два выхода (вариант “бросить нафиг это гиблое дело” мы пока что рассматривать не будем), первый из которых совсем не исключает второго: придется вложить кучу денег в оборудование и/или найти путь снизить требования приложения к памяти.

На самом деле, хранение большого количества данных в пользовательской сессии на сервере само по себе не очень хорошая затея. Пользовательские сессии содержат в себе по сути копии объектов данных, и эти копии обычно быстро становятся устаревшими. Так, если некий пользователь Вася случайно нажмет кнопку “Назад” в браузере, то он может быть немного озадачен: “Что произошло? Я же уже вводил здесь информацию о своем любимом коте!”. И еще, чем больше пользователей, тем больше копий одного и того же объекта будет храниться в памяти. А это пустая трата памяти, которая могла бы быть использована для других данных и пользователей.

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

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

Выходом здесь может быть реализация механизма кэширования. Во-первых, помещение небольшого кэша между базой данных и web-сервером позволяет быть уверенным, что единовременно только одна копия объекта данных содержится в памяти. Во-вторых, кэш - на то он и “небольшой” - может быть сконфигурирован таким образом, чтобы использовать только определенное количество памяти. И это позволит нам всегда иметь доступную память для обработки запросов и хранения данных новых, долгожданных пользователей!