IBM WebSphere Developer Technical Journal: Использование Spring и Hibernate с WebSphere Application Server

Что делать, и чего вы должны остерегаться

Если вы подумываете об использовании Spring или Hibernate с IBM® WebSphere® Application Server, эта статья обязательна для чтения. В ней объясняется, как вы должны настроить эти интегрированные среды для различных сценариев с WebSphere Application Server. Описаны также не поддерживаемые сценарии, которых нужно остерегаться. Эта статья не является одобрением или рекомендацией использовать какую-либо интегрированную среду; она - необходимый справочник для тех, кто решил реализовать такой сценарий.

Том Элкот, специалист-консультант по информационным технологиям, IBM

Том Элкот (Tom Alcott) работает консультантом по информационным технологиям в IBM, США. Является членом группы Worldwide WebSphere Technical Sales Support с момента ее образования в 1998 году. В этой роли он проводит подавляющую часть своего времени, пытаясь быть на одну страницу руководства впереди пользователей. До начала работы с WebSphere он работал системным инженером в IBM Transarc Lab, осуществляющей поддержку TXSeries. Имеет более чем 20-летний опыт проектирования и разработки систем для универсальных ЭВМ и распределенных систем. Он часто пишет на многие темы среды времени исполнения WebSphere.



Роланд Баркиа, сертифицированный специалист по информационным технологиям, IBM

Роланд Баркиа (Roland Barcia) работает консультантом по информационным технологиям в IBM Software Services for WebSphere в районе New York/New Jersey Metro. Является соавтором руководства "IBM WebSphere: Развертывание и продвинутая настройка". Дополнительная информация о Роланде приведена на его сайте.



Джим Кнутсон, проектировщик WebSphere J2EE, IBM

Джим Кнутсон (Jim Knutson) является разработчиком WebSphere J2EE. Джим отвечает за участие IBM в связанных с J2EE спецификациях. Джим также принимает участие в развитии программной модели для поддержки SOA и Web-служб.



20.09.2006

Взято из IBM WebSphere Developer Technical Journal.

Введение

Spring и Hibernate - это два проекта с открытыми исходными кодами, использованием которых могут заинтересоваться некоторые заказчики. В данной статье описывается, как настроить эти интегрированные среды для различных сценариев использования совместно с WebSphere Application Server. Однако данная статья не является одобрением или рекомендацией использовать какую-либо интегрированную среду. Ни один из этих проектов с открытыми исходными кодами не поддерживается непосредственно IBM. IBM поддерживает ограниченное использование этих интегрированных прикладных сред (как описано ниже) точно так же, как поддерживает любое пользовательское приложение, работающее на WebSphere Application Server. В данной статье описываются также не поддерживаемые сценарии, которых нужно избегать в обоих продуктах (в WebSphere Application Server и в продуктах семейства WebSphere).


Техническая поддержка пользователя и продукта

Областью обоснованных интересов пользователей является поддержка проектов, использующих открытые исходные коды, и влияние этого использования на поддержку производителем его лицензированных продуктов. IBM осознает, что некоторые пользователи могут захотеть использовать совместно с IBM WebSphere Application Server интегрированные среды не от фирмы IBM, и предоставляет информацию, которая может способствовать созданию наиболее надежной рабочей среды для IBM WebSphere Application Server. IBM рассматривает установленные пользователями открытый исходный код и прикладные интегрированные среды (объединенные либо как часть приложения, либо в виде совместно используемых библиотек) как часть кода приложения. Внимательно применяя эту информацию при использовании проектов с открытым исходным кодом, пользователи могут использовать IBM-продукты с большей степенью уверенности в том, что они будут иметь постоянный доступ к продукту IBM и технической поддержке. Если при использовании этих интегрированных сред с продуктами WebSphere возникнет проблема, IBM приложит все усилия, для того чтобы убедиться в том, что проблема не относится к продукту WebSphere.

Ожидается, что пользователи могут благополучно использовать такие интегрированные среды как Spring и Hibernate с продуктами IBM, придерживаясь рекомендаций данной статьи, избегая указанных ситуаций и понимая несколько ключевых моментов:

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

  • Используя интегрированные среды с открытым исходным кодом совместно с WebSphere Application Server, пользователи должны убедиться в том, что они понимают и имеют доступ к соответствующим исходным кодам и двоичным файлам соответствующей среды.

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

Дополнительные подробности по поддержке и политике IBM приведены в "Справочнике по службе поддержки IBM" и в "WebSphere Application Server Support Statement".

Хотя приведенные далее в этой статье рекомендации помогут вам улучшить ваши знания в использовании WebSphere Application Servers в среде с открытым исходным кодом, это не всеобъемлющий список способов, которыми компонент с открытым исходным кодом может повлиять на функционирование WebSphere Application Server или функционирование других компонентов. Пользователи открытого исходного кода должны внимательно просматривать спецификации всех компонентов для устранения проблем по лицензированию и поддержке, а также технических проблем.

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


Hibernate

Hibernate - это устойчивая интегрированная среда с открытыми исходным кодами для Plain Old Java™ Objects (POJO), обеспечивающая объектно-ориентированное отображение объектов POJO в таблицы реляционной базы данных с использованием конфигурационных XML-файлов. Интегрированная среда Hibernate - это абстрактный уровень доступа к данным, вызываемый вашим приложением для персистенции данных. Кроме того, Hibernate предоставляет отображение Java-классов на таблицы базы данных (и типов данных Java на типы данных SQL), а также возможности запросов к данным и их извлечения. Hibernate генерирует необходимые SQL-вызовы, а также заботится об обработке набора результатов и преобразовании объектов.

Hibernate был разработан командой программистов во главе с Гэвином Кингом (Gavin King), который основал Hibernate Project, для того чтобы преодолеть несколько недостатков, существующих в EJB 2.x компонентах управления данными. Hibernate тесно связан с JBoss Group как результат найма фирмой JBoss нескольких ведущих разработчиков Hibernate. Совсем недавно Hibernate был вовлечен в развитие персистентных интегрированных сред в Java Community Process (JCP), а многие концепции Hibernate были введены в спецификацию Java Persistence APIs (JPA). Самая последняя версия Hibernate разработана в соответствии со спецификацией JPA. По всей видимости, JPA станет доминирующим API Java-персистенции. В частности, JPA является обязательной частью Java EE 5 (ссылки на статьи developerWorks по использованию Hibernate приведены в разделе "Ресурсы").

IBM не предоставляет прямой поддержки Hibernate, хотя поддерживается использование Hibernate на WebSphere Application Server, как описано ниже. Любой пользователь Hibernate должен получить поддержку согласно описанию на странице Hibernate Project Support. Пользователи должны сохранить соответствующий исходный код используемого ими проекта с открытым исходным кодом для получения помощи в решении проблем.

Сценарии использования

Следующие сценарии описывают некоторые возможные сценарии использования Hibernate с WebSphere Application Server с продуктами семейства WebSphere. Это только примерные сценарии, которые не должны рассматриваться как рекомендованные. Как упоминалось ранее, пользователи должны сохранить соответствующий исходный код используемого ими проекта с открытым исходным кодом для получения помощи в решении проблем.

Использование WebSphere Application Server DataSource

Для получения соединения Hibernate с базой данных из WebSphere Application Server нужно использовать ссылку на ресурс, как установлено в спецификации Java EE (ранее известной как J2EE). Это гарантирует способность WebSphere Application Server обеспечить корректное поведение для организации пула соединений, семантики транзакций и уровней изоляции. Hibernate настраивается на извлечение DataSource из WebSphere Application Server путем установки свойства hibernate.connection.datasource (определенного в конфигурационном файле Hibernate) в ссылку на ресурс (например, java:comp/env/jdbc/myDSRef), определенный в дескрипторе развертывания модуля. Например:

<property name="hibernate.connection.datasource">
	java:/comp/env/jdbc/myDSRef
</property>

Ссылки на ресурсы Java EE для Web-приложений определены на уровне WAR-файла. Это означает, что все сервлеты и Java-классы внутри контейнера совместно используют ссылку на ресурс. Внутри EJB-модуля ссылка на ресурс определяется для индивидуальных EJB-компонентов. Это означает, что если многие EJB-компоненты используют одну и ту же конфигурацию Hibernate, каждый EJB должен определять одно и то же имя ссылки для каждого EJB-компонента. Это может привести к сложностям, которые мы обсудим немного позже.

После конфигурирования DataSource одним из следующих действий (для гарантирования корректной работы Hibernate) является правильная настройка поддержки транзакций.

Конфигурация стратегии транзакций

Для коректной работы с транзакциями Hibernate требует конфигурирования двух важных частей: во-первых, hibernate.transaction.factory_class, определяющего транзакционное управление, и, во-вторых, hibernate.transaction.manager_lookup_class, определяющего механизм регистрации синхронизации транзакции, для того чтобы менеджер персистенции уведомлялся о завершении транзакции тогда, когда требуется синхронизация изменений с базой данных. Для транзакционного управления поддерживаются обе конфигурации - управляемая контейнером и управляемая компонентом. Следующие свойства должны быть установлены в Hibernate.cfg.xml при использовании Hibernate с WebSphere Application Server:

  • для управляемых контейнером транзакций:

    <property name="hibernate.transaction.factory_class">
    	org.hibernate.transaction.CMTTransactionFactory
    </property>
    <property name="hibernate.transaction.manager_lookup_class">
    	org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
    </property>
  • для управляемых компонентом транзакций:

    <property name="hibernate.transaction.factory_class">
    	org.hibernate.transaction.JTATransactionFactory
    </property>
    <property name="hibernate.transaction.manager_lookup_class">
    	org.hibernate.transaction.WebSphereExtendedJTATransactionLookup
    </property>
    <property name="jta.UserTransaction">
    	java:comp/UserTransaction
    </property >

Свойство jta.UserTransaction конфигурирует класс фабрики для получения экземпляра объекта UserTransaction из контейнера WebSphere.

Свойство hibernate.transaction.manager_lookup_class поддерживается на платформе WebSphere серверами WebSphere Application Server V6.x и старше, а также WebSphere Business Integration Server Foundation V5.1 и старше. Это свойство конфигурирует Hibernate на использование интерфейса ExtendedJTATransaction, который был представлен в WebSphere Business Integration Server Foundation V5.1 и WebSphere Application Server V6.0. Интерфейс WebSphere ExtendedJTATransaction устанавливает шаблон, формализованный в спецификации Java EE 5 через JTA 1.1.

Шаблоны использования Hibernate в среде WebSphere Application Server

Оба шаблона Hibernate, session-per-request (сессия на запрос) и long conversation (продолжительный диалог), доступны при использовании Hibernate с WebSphere Application Server. Пользователи должны выбрать, что подходит для их приложения, хотя, по нашему мнению, шаблон session-per-request предлагает лучшую масштабируемость.

  • Несколько уровней изоляции

    Разделяемые соединения обеспечивают повышение производительности в WebSphere Application Server путем разрешения нескольким пользователям ресурса совместно использовать существующие соединения. Однако, если необходимы и разделяемые соединения и несколько уровней изоляции, определяйте отдельные resource-ref и Hibernate session-factory для конфигурации каждого соединения. Не существует возможности изменить уровень изоляции разделяемого соединения. Следовательно, невозможно также использовать свойство hibernate.connection.isolation для установки уровня изоляции на разделяемом соединении. Дополнительная информация по политикам и ограничениям разделения соединений приведена в статье "Разделяемые соединения WebSphere Application Server V5". Хотя в данной статье обычно имеется в виду использование разделяемых соединений с WebSphere Application Server V5, совет по разделению соединений также относится к Hibernate, выполняющемуся на V6.x.

  • Web-приложения

    Hibernate-сессии long conversation могут быть использованы и сохранены в объектах HttpSession; однако Hibernate-сессии хранят активные экземпляры и, следовательно, сохранение их в HttpSession может не быть масштабируемым шаблоном, поскольку может потребоваться сериализация или репликация сессий на дополнительные члены кластера. Лучше использовать HttpSession для хранения отсоединенных объектов (поскольку они малы по размерам - от 10KB до 50KB) и повторно связывать их с новой Hibernate-сессией при необходимости обновления. HttpSession лучше всего подходит для установки закладок, а не для кэширования. Дискуссия о том, как минимизировать использование оперативной памяти в HttpSession, приведена в статье "Улучшение производительности HttpSession при помощи интеллектуальной сериализации". Вместо использования HttpSession в качестве кэша подумайте об использовании технологии кэширования данных в WebSphere (такой как ObjectGrid или DistributedObjectCache), которая описана в следующем разделе.

Очень рекомендуем познакомиться с лучшими примерами высокопроизводительных и масштабируемых приложений, приведенные в книге "Анализ производительности для Web-сайтов, использующих технологию Java".

Интегрирование кэша второго уровня

Hibernate-сессия предоставляет область видимости для единицы работы. На протяжении жизненного цикла Hibernate-сессии персистенцией управляет интерфейс Session. В общем случае он это делает путем обслуживания состояния отображенных экземпляров классов сущностей, за которые он несет ответственность, сохраняя кэш первого уровня интерфейсов, корректный для единичного потока. Кэш удаляется после завершения единицы работы (сессии). Может быть также настроен кэш второго уровня для совместного использования всеми сессиями SessionFactory, в том числе по всему кластеру. Помните о том, что кэширование в Hibernate поднимает вопросы, которые должны быть решены. Во-первых, не делается попыток гарантировать целостность кэша ни относительно внешних изменений в базе данных, ни относительно всего кластера (пока не будет использован кэш на уровне кластера). Во-вторых, другие уровни (например, база данных) могут уже иметь кэш, уменьшая значение кэша Hibernate. Данные вопросы должны быть тщательно исследованы при проектировании приложения, но это выходит за рамки нашей статьи.

На дату публикации поведение кэшей Hibernate уровня кластера в соединении с WebSphere Application Server не определено; следовательно, еще не определено, поддерживается или нет их использование, и мы больше не будем их обсуждать. Поэтому пользователи, которым необходим распределенный кэш, должны подумать о создании класса, который реализует org.hibernate.cache.CacheProvider, используя свойство hibernate.cache.provider_class, которое предоставляет одну из двух реализаций распределенного кэша в WebSphere.

Hibernate поставляется с несколькими предварительно настроенными кэшами. Информация о них приведена на страницах документации Hibernate Cache. Для данных, доступ к которым осуществляется только для чтения, может быть достаточно наличия кэшей, организованных в оперативной памяти. Однако, когда приложение кластеризовано и необходим кэш на уровне кластера, таких локальных кэшей недостаточно. Если желателен распределенный кэш, мы рекомендуем использовать одну из предоставляемых в WebSphere реализаций распределенного кэша. Они могут использоваться с Hibernate в качестве кэша второго уровня:

Использование Hibernate в WebSphere Enterprise Service Bus и WebSphere Process Server

WebSphere Process Server и WebSphere Enterprise Service Bus (ESB) основаны на Service Component Architecture (SCA) и Service Data Objects (SDO), как моделях компоновки и программирования для SOA (ссылки на дополнительную информацию по SCA и SDO приведены в разделе "Ресурсы"). SCA-компоненты не являются компонентами Java EE, поэтому они не имеют ссылок на ресурсы, а основаны на службах и адаптерах для соединения с системами. Ссылки на ресурсы не могут быть использованы при создании Java SCA-компонентов; следовательно, Hibernate не может использоваться SCA-компонентом напрямую.

В этой ситуации Hibernate-персистенция должна быть скрыта за некоторого рода фасадом (facade). Здесь есть две альтернативы:

  • Для заключения в себя Hibernate-персистенции создается локальный фасад EJB-сессии. Фасад сессии предоставляет логику адаптера для отображения сущностных POJO Hibernate на объекты Service Data Objects и обратно. Разработчик интеграции может затем использовать импорт EJB для активизации фасада сессии и активизировать его с соответствующим качеством обслуживания (Qualities of Service - QoS).

  • Для заключения в себя Hibernate-персистенции создается фасад сессии EJB Web-службы. Разработчик интеграции может затем использовать импорт Web-службы для активизации Web-службы для персистенции. Речь идет о необходимости создания преобразователей POJO в SDO, поскольку в настоящее время SCA использует SDO только для типов данных. На рисунке 1 изображен бизнес-процесс, использующий обе схемы. Детали процесса выходят за рамки данной статьи.

Рисунок 1. Пример бизнес-процесса
Рисунок 1. Пример бизнес-процесса

Hibernate JPA API на WebSphere Application Server V6.1

Для стандартной JPA-персистенции в Hibernate предоставляется поддержка JPA, которая является хорошей альтернативой лицензированным Hibernate API. Реализация JPA в Hibernate требует наличия системы времени исполнения, основанной на Java EE 5, и, следовательно, работает только на WebSphere Application Server V6.1 или старше. На дату публикации данной статьи поддержка JPA в Hibernate не работает на платформах WebSphere z/OS и iSeries. В документации по Hibernate описано, как спакетировать и развернуть приложения, используя JPA-реализацию в Hibernate.

Моменты, которых нужно избегать

В следующем разделе описаны не поддерживаемые конфигурации и варианты использования. Описываются только идентифицированные в настоящее время не поддерживаемые варианты. В будущем могут быть идентифицированы дополнительные не поддерживаемые варианты.

Не поддерживаемые конфигурации транзакций

В документации Hibernate описываются конфигурации стратегии транзакций для работы на продуктах WebSphere Application Server Version 4 и 5, но эти конфигурации используют внутренние интерфейсы WebSphere и не поддерживаются на этих старых версиях. Единственная поддерживаемая конфигурация транзакций Hibernate описана в приведенном выше разделе "Конфигурация стратегии транзакций". Как упоминалось ранее, это означает, что использование Hibernate поддерживается только на WebSphere Application Server V6.x и WebSphere Business Integration Server Foundation V5.1.

Невзаимодействующие / непереносимые функции

В разделе 3.2.4.2 спецификации JPA описан сценарий, который, вероятно, вызывает потенциальные проблемы взаимодействия и переносимости. Он имеет дело с использованием "ленивой" (lazy) загрузки (т.е., @Basic(fetch=LAZY)) и изолированных объектов. При объединении изолированного объекта обратно в сессию, JPA будет проверять объект и обновлять хранилище данных всеми изменившимися значениями. Однако объекты данных - это простые POJO-объекты. Если часть состояния POJO-объекта не была загружена при его отсоединении, он может измениться при обратном присоединении. Для того чтобы это работало корректно, производители должны реализовать методы сериализации, специфичные для их систем времени исполнения. Они не способны взаимодействовать, а их семантика может быть также и не переносимой.


Spring

Spring обычно описывается как облегченная среда контейнеров, хотя, возможно, более правильно описать ее как интегрированную среду для упрощения разработки. Ее основной концепцией является использование внедрения зависимостей (dependency injection - DI) и аспектно-ориентированного программирования (Aspect Oriented Programming - AOP) для упрощения и сглаживания перехода от разработки к тестированию и производству.

Интегрированная среда Spring - среда с открытыми исходными кодами, которая была разработана фирмой Interface21, Inc. на основе публикаций Рода Джонсона (Rod Johnson) по шаблону проектирования Dependency Injection (DI) (внедрение зависимостей). Spring может использоваться как автономное приложение, а также совместно с серверами приложений. Поскольку некоторые из служб, предоставляемых Spring, обычно предоставляются системой времени исполнения сервера приложений, использование Spring с серверами приложений должно быть тщательно разработано для устранения конфликтов между реализацией Spring и реализацией, предоставляемой сервером приложений.

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

IBM не предоставляет прямой поддержки Spring, хотя на WebSphere Application Server поддерживается ограниченное использование Spring, как описывается ниже. Любой пользователь Spring должен получить поддержку согласно описанию на странице Spring Project Support. Пользователи должны сохранить соответствующий исходный код используемого ими проекта с открытым исходным кодом для получения помощи в отладке проблем.

Сценарии использования

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

Простой логический контейнер компонентов

Одним из наиболее часто применяемых сценариев использования Spring является настройка и выполнение бизнес-логики, используя простые Java-классы компонентов. Spring-приложения, которые избегают описанных ниже проблематичных сценариев, не должны иметь проблем с выполнением в среде времени исполнения WebSphere Application Server. Страница документации Spring предоставляет достаточно информации для создания приложения, использующего Spring-компоненты. Здесь нет ничего специфичного для WebSphere.

Использование интегрированной среды Spring DAO в WebSphere

Здесь приведены три примера использования функциональных возможностей Spring DAO на WebSphere Application Server:

  • Базовое использование DAO

    WebSphere Application Server управляет ресурсами, используемыми внутри среды исполнения сервера приложений. Spring-приложения, которые хотят обратиться к таким ресурсам как JDBC DataSources, должны использовать управляемые WebSphere ресурсы. Существует несколько шагов, которые необходимо выполнить для этого.

    1. Во время развертывания WAR-модуль должен быть настроен с ссылкой на ресурс. Например:

      <resource-ref>
      	<res-ref-name>jdbc/springdb</res-ref-name>
      	<res-type>javax.sql.DataSource</res-type>
      	<res-auth>Container</res-auth>
      	<res-sharing-scope>Shareable</res-sharing-scope>
      </resource-ref>
    2. Для EJB JAR-файлов та же resource-ref должна быть объявлена в каждом EJB, который обращается к DataSource.

    3. Компонент DataSource должен быть объявлен внутри конфигурационного файла Spring при помощи чего-нибудь, аналогичного следующему:

      <bean id="WASDataSource" 
          class="org.springframework.jndi.JndiObjectFactoryBean">
      	<property name="jndiName" 
      		value="java:comp/env/jdbc/springdb"/>
      	<property name="lookupOnStartup" 
      		value="false"/>
      	<property name="cache" 
      		value="true"/>
      	<property name="proxyInterface" 
      		value="javax.sql.DataSource"/>
      </bean>

      Это настроит компонент на поиск DataSource в настроенных в модуле ссылках. Обратите внимание на то, что значение свойства jndiName соответствует шаблону java:comp/env/, объединенному с res-ref-name и объявленному в resource-ref.

    4. Компонент DataSource теперь может использоваться Spring-приложением.

    5. Когда приложение развертывается на WebSphere Application Server, провайдер ресурсов и источник данных ресурсов должны быть настроены для использования ссылкой на ресурс Spring-приложения. Ссылка на ресурс, объявленная в дескрипторе развертывания модуля, будет связана с настроенным на сервере приложений источником данных во время развертывания.

  • Использование транзакций DAO

    Существует несколько способов выполнять обновления ресурса в Spring под управлением транзакций. К ним относятся как программные, так и декларативные формы. Декларативные формы бывают аннотированными и не аннотированными. При использовании в Spring поддержки транзакций важно правильно настроить использование средой Spring имеющегося менеджера транзакций. Единственной формой использования менеджера транзакций средой Spring на WebSphere Application Server является:

    <bean d="transactionManager"
    class="org.springframework.transaction.jta.JtaTransactionManager">
    	<property name="autodetectTransactionManager"
    		value="false"/>
    </bean>

    Компонент менеджера транзакций может предоставляться классам JdbcTemplate, а также использоваться через декларативные формы политики транзакций. Дополнительная информация о том, почему это единственная форма, приведена в разделе "Чего следует избегать".

  • Использование Hibernate DAO

    Spring документирует базовую настройку использования Hibernate совместно со Spring. При использовании в среде WebSphere Application Server будет необходимо объединить требования по конфигурации для Hibernate и Spring, описанные выше. Необходимы также использование JNDI для доступа к ресурсам и правильная настройка системы управления транзакциями как в Spring, так и в Hibernate, что описано выше.

Spring Web MVC

Интегрированная среда Spring Web MVC является альтернативой другим средам, существующим на рынке некоторое время. Интегрированная среда Web MVC, поставляемая, используемая и поддерживаемая сервером WebSphere Application Server, включает JSF и Struts. Справочное руководство по Spring описывает, как интегрировать Spring с этими интегрированными Web-средами. Использование любой из вышеперечисленных сред поддерживается сервером WebSphere Application Server, хотя IBM предоставляет только не полную поддержку интегрированных сред, поставляемых с WebSphere Application Server.

Планирование и организация пулов потоков

Если нужно выполнить код асинхронно, то следует использовать WorkManagerTaskExecutor. Это единственная реализация TaskExecutor в Spring, которая использует пулы Thread, управляемые сервером WebSphere Application Server. Другие реализации TaskExecutor могут запустить неуправляемые потоки. Дополнительная информация по неуправляемым потокам приведена в разделе "Чего следует избегать".

WorkManager настраивается в административной консоли WebSphere Application Server путем перехода в Resources => Asynchronous beans => Work managers. JNDI-имя ресурса затем может использоваться в конфигурационном файле Spring для определения WorkManagerTaskExecutor.

Spring-портлеты

Spring-портлеты выполняются в обоих контейнерах портлетов - WebSphere Portal V6.0 и WebSphere Application Server V6.1. Пример набора Spring-портлетов приведен в Spring Portlet MVC. Запуск портлетов в контейнере портлетов WebSphere Application Server V6.1 требует создания дополнительного Web-приложения для определения схемы и агрегирования портлетов. Информация по использованию библиотеки тегов агрегирования портлетов приведена в WebSphere Application Server Information Center. Так же дополнительная вспомогательная информация приведена в статье "Введение в контейнер портлетов".

Обычно, JSF используется совместно с портлетами для визуализации. Информация по совместной работе Spring, Hibernate, JSF и WebSphere Portal приведена в статье "Настройка Hibernate, Spring, Portlets и OpenInSessionViewFilter с IBM WebSphere Portal Server".

Чего следует избегать

Замечено, что следующие сценарии являются проблематичными в среде WebSphere Application Server и их следует избегать. Существует ряд причин, по которым эти сценарии вошли в список, однако самой общей причиной является использование внутренних интерфейсов WebSphere средой Spring. Использование этих внутренних интерфейсов подрывает способность WebSphere Application Server гарантировать целостность среды приложений и управлять ресурсами приложений. Следует избегать использования любых функций Spring, которые основаны на внутренних интерфейсах WebSphere.

Политики транзакций REQUIRES_NEW и NOT_SUPPORTED

WebSphere Application Server обеспечивает устойчивую среду для поддержки целостности данных. Одним из методов такого обеспечения является постоянная гарантия выполнения логики приложения внутри транзакции. Когда контейнер собирается выполнить бизнес-логику, он проверяет состояние транзакции. Если глобальная транзакция не активна, контейнер создает и поддерживает новый контекст ограничения распространения локальной транзакции (local transaction containment - LTC). Контейнер завершает LTC в конце бизнес-логики и приостанавливает ее на протяжении любой инициированной приложением глобальной транзакции. Это гарантирует постоянную корректную очистку ресурсов в конце выполнения бизнес-логики.

Среда Spring предоставляет механизм для управления транзакциями. Однако поддерживаемые ею политики транзакций выходят за рамки набора политик, которые в нормальной ситуации могут обрабатываться на прикладном уровне. В частности, она предоставляет свою собственную эквивалентную поддержку управляемых контейнером EJB-семантик REQUIRES_NEW и NOT_SUPPORTED. Обе эти управляемые контейнером политики требуют наличия способности приостанавливать и продолжать транзакции, но такая способность зарезервирована для использования EJB-контейнера (некорректное использование могло бы вызвать появление проблем целостности данных). Для обеспечения такого поведения Spring использует внутренние интерфейсы WebSphere, не зная их влияния на контейнер. Остановка и продолжение транзакций с использованием внутренних интерфейсов подвергает риску способность Web и EJB-контейнеров управлять ресурсами и LTC, а также может оставить контейнер в неизвестном состоянии, вызывая, возможно, повреждение данных.

Нужно выполнить два условия, для того чтобы избежать такого сценария:

  • Не использовать политики транзакций Spring, которые требуют семантик остановки и продолжения.
  • Не конфигурировать Spring JtaTransactionManager для поддержки семантик остановки и продолжения.

Первое - это ограничение во время проектирования приложения. Если вы создаете приложение, не проектируйте семантики, требующие использования Spring для остановки и продолжения транзакций. Если семантики остановки и продолжения необходимы, используйте вместо них не сохраняющие состояния (stateless) сессионные EJB-компоненты.

Второе - это ограничение настройки во время развертывания. Если Spring-приложение развертывается на WebSphere Application Server, оно потерпит неудачу при попытке использовать семантики Spring остановки и продолжения. Лучше потерпеть, таким образом, неудачу, чем получить ошибки случайного повреждения данных. Вот правильный способ того, как должен быть настроен Spring JtaTransactionManager в WebSphere Application Server:

<bean id="transactionManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
	<property name="autodetectTransactionManager" 
		value="false"/>
</bean>

Это настроит компонент transactionManager на использование UserTransaction API для управления началом, подтверждением и откатом транзакций. При этом управление транзакциями разрешится без семантики остановки и продолжения.

Использование Spring JtaTransactionManager описанным выше способом не поддерживает функциональную возможность Spring регистрации синхронизации с существующими транзакциями. Для того чтобы это делать, необходимо использовать WebSphereTransactionManagerFactoryBean. Пользователи, использующие WebSphereTransactionManagerFactoryBean или любой другой класс, вызывающий интерфейсы внутреннего менеджера транзакций, не будут поддерживаться.

JDBC-соединения

Spring предоставляет механизм доступа к родным соединениям, когда различные JDBC-операции требуют взаимодействия с родным JDBC-ресурсом. Классы JdbcTemplate используют эту способность, когда класс NativeJdbcExtractor установлен на класс JdbcTemplate. Как только класс NativeJdbcExtractor устанавливается, Spring всегда добирается до родного JDBC-соединения при использовании с WebSphere Application Server, обходя, таким образом, следующие функциональные возможности и преимущества WebSphere QoS:

  • Отслеживание и повторное назначение идентификатора соединения.
  • Совместное использование соединения.
  • Состояние транзакции.
  • Управление пулом.
  • Участие транзакции последнего агента.

Еще одной проблемой является зависимость класса WebSphereNativeJdbcExtractor от внутренних классов адаптеров WebSphere. Эти внутренние классы могут отличаться в разных версиях WebSphere Application Server, а также могут быть изменены в будущем, что, таким образом, нарушит приложения, которые зависят от этой функциональности.

Использование реализаций класса NativeJdbcExtractor (например, WebSphereNativeJdbcExtractor) не поддерживается на WebSphere Application Server, и пользователи должны избегать сценариев, которые требуют их наличия. Альтернативой является использование класса WSCallHelper сервера WebSphere Application Server для доступа к нестандартным расширениям DataSources других производителей.

Подводный мир загрузчиков классов

Spring и WebSphere Application Server используют несколько проектов с открытыми исходными кодами, и, к сожалению, версии имеющихся в них общих проектов не всегда совпадают. Spring-зависимости должны быть спакетированы как часть приложения, а сервер для обхода конфликтов должен быть настроен так, как описано ниже. В противном случае загрузчики классов (classloaders) могут не загрузить соответствующую версию либо среды времени исполнения, либо приложения. Как правило, это вызывает генерирование в log-файле исключительных ситуаций ClassCastExceptions либо java.lang.VerifyErrors, относящихся к несоответствию классов в версиях.

Одним примером является использование Jakarta Commons Logging. Конфигурирование Jakarta Commons Logging (JCL) для использования приложением или использование версии JCL, отличной от предоставляемой сервером приложений (например, встроенной в код приложения), требует специальной настройки WebSphere Application Server. Стратегии настройки развертываемого приложения для использования встроенной версии широко используемых технологий приведены в статье "Интегрирование Jakarta Commons Logging". Следите на Web-сайте поддержки за обновлениями информации о конфигурировании встроенного JCL на продуктах WebSphere Application Server V6.x. Это только один пример конфликтов. Другие примеры могут включать использование приложением JDOM или специфичных версий JavaMail. Замена JAR-файлов WebSphere Application Server в этих или других пакетах более старших или различных версий не поддерживается.

Еще одной проблемой загрузчика классов, которая может мучить пользователей Spring на сервере WebSphere Application Server, является способ, каким Spring загружает ресурсы. Ресурсы могут содержать такие вещи, как наборы сообщений; с иерархией загрузчика классов и различными политиками для обнаружения ресурсов в иерархии существует возможность обнаружить ресурсы, использующие общее имя, в непредсказуемых местах. Просмотрщик загрузчика классов WebSphere Application Server может использоваться для помощи в решении этой проблемы. Комбинирование этой и включение других версий общих библиотек может потребовать переименования (на уникальное имя) ресурсов в приложении.

Неуправляемые потоки

Существует несколько Spring-сценариев, которые могут привести к созданию неуправляемых потоков. Неуправляемые потоки неизвестны серверу WebSphere Application Server и не имеют доступа к информации о контексте Java EE. Кроме того, они могут использовать ресурсы без ведома WebSphere Application Server и существовать вне способности администратора контролировать их количество и используемые ресурсы, а также препятствуют возможности сервера приложений правильно перезагружаться или восстанавливать ресурсы после сбоя. Приложения должны избегать любого сценария, который запускает неуправляемые потоки:

  • registerShutdownHook

    Первый сценарий - использование Spring AbstractApplicationContext или одного из его подклассов. Существует public-метод registerShutdownHook, который создает поток и регистрирует его в Java VM для выполнения при останове сервера с целью закрытия ApplicationContext. Приложения могут избежать этого, используя обычные уведомления жизненного цикла, которые они получают от контейнера WebSphere, для явного вызова функции закрытия ApplicationContext.

  • Входящие JMS-сообщения

    Классы Spring JMS MessageListenerContainer используют классы, которые запускают неуправляемые потоки (например, SimpleAsyncTaskExecutor) для прослушивания входящих JMS-сообщений. При этом не только запускаются неуправляемые потоки, но и JMS-контейнеры Spring используют JMS API, которые не предполагается вызывать приложениями в среде Java EE (подробности приведены в разделе J2EE.6.6 спецификации Java EE).

    Spring remoting API могут использоваться для создания JMS-сообщений, но пользователи должны использовать управляемые сообщениями компоненты для обработки входящих сообщений и избегать Spring JMS MessageListenerContainer. Это позволяет корректно контролировать и восстанавливать ресурсы и транзакции контейнером.

  • JMX-серверы

    Приложения должны избегать использования Spring JMX ConnectorServerFactoryBean, еще одного класса, запускающего неуправляемые потоки. WebSphere Application Server уже предоставляет JMX-сервер с поддержкой нескольких протоколов коннекторов. Приложения могут зарегистрировать MBeans с JMX-сервером WebSphere Application Server и обращаться к ним удаленно.

  • Не интегрированные пакеты планирования

    Spring предоставляет или интегрирует несколько пакетов планирования. Единственным пакетом планирования Spring, который работает с потоками, управляемыми сервером WebSphere Application Server, является пакет CommonJ WorkManager. Остальные пакеты, такие как quartz и JDK Timer, запускают неуправляемые потоки, поэтому их использования следует избегать.

  • WeakReferenceMonitor

    Spring предоставляет удобные классы для упрощения разработки EJB-компонентов. Помните о том, что эти удобные классы порождают неуправляемые потоки, используемые WeakReferenceMonitor в целях очистки.


Заключение

Существует возможность использования Hibernate и Spring на платформе WebSphere с полной поддержкой, но при условии того, что будет уделено достаточное внимание обходу проблемных сценариев. В частности, пользователи должны гарантировать, что эти интегрированные среды не используют внутренние интерфейсы WebSphere. Пользователи, имеющие проблемы с использованием WebSphere Application Server совместно с Spring или Hibernate, а также имеющие право на IBM-поддержку WebSphere Application Server, могут ожидать получения помощи в диагностировании проблемы, пока не будет определено, что используются не поддерживаемые сценарии, или IBM не определит, что проблема не в WebSphere Application Server. Пользователи должны договориться о получении поддержки по интегрированным средам Hibernate и Spring от других компаний, как указано на Web-сайтах соответствующих проектов.


Благодарности

Авторы хотели бы поблагодарить Яна Робинсона (Ian Robinson), Кейза Ботсума (Keys Botzum), Пола Глезена (Paul Glezen), Томаса Сэндвика (Thomas Sandwick), Боба Коньерса (Bob Conyers) и Нейла Ларавэя (Neil Laraway) за их комментарии и участие в работе над статьей.

Ресурсы

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Профиль создается, когда вы первый раз заходите в developerWorks. Информация в вашем профиле (имя, страна / регион, название компании) отображается для всех пользователей и будет сопровождать любой опубликованный вами контент пока вы специально не укажите скрыть название вашей компании. Вы можете обновить ваш IBM аккаунт в любое время.

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=WebSphere, Open source
ArticleID=174022
ArticleTitle=IBM WebSphere Developer Technical Journal: Использование Spring и Hibernate с WebSphere Application Server
publish-date=09202006