Подтвердить что ты не робот

Как модулировать приложение JSF/Facelets/Spring с OSGi?

Я работаю с очень большими приложениями JSF/Facelets, которые используют Spring для управления DI/bean. Мои приложения имеют модульную структуру, и в настоящее время я ищу подходы к стандартизации модуляции.

Моя цель - составить веб-приложение из нескольких модулей (возможно, в зависимости от друг друга). Каждый модуль может содержать следующее:

  • Классы;
  • Статические ресурсы (изображения, CSS, скрипты);
  • Шаблоны Facelet;
  • Управляемые beans - Spring контексты приложения с запросом, сеансом и областью beans (альтернатива - управляемая JSF beans);
  • Servlet API - сервлеты, фильтры, прослушиватели (это необязательно).

То, что я хотел бы избежать (почти любой ценой), - это необходимость скопировать или извлечь ресурсы модуля (например, шаблоны Facelets) в WAR или расширить web.xml для сервлетов, фильтров и т.д. Это необходимо достаточно добавить модуль (JAR, bundle, artifact,...) в веб-приложение (WEB-INF/lib, bundles, plugins,...), чтобы расширить веб-приложение с помощью этого модуля.

В настоящее время я решаю эту задачу с помощью специального решения для модуляции, которое основано на использовании ресурсов classpath:

  • Сервлет специальных ресурсов обслуживает статические ресурсы из ресурсов класса (JAR).
  • Специальный ресивер ресурса Facelets позволяет загружать шаблоны Facelet из ресурсов pathpath.
  • Spring загружает контексты приложений с помощью шаблона classpath*:com/acme/foo/module/applicationContext.xml - это загружает контексты приложений, определенные в JAR модуля.
  • Наконец, пара делегирующих сервлетов и фильтров делегирует обработку запросов сервлетам и фильтрам, сконфигурированным в контекстах приложений Spring из модулей.

В последние дни я много читал о OSGi, и я рассматривал, как (и если) я мог бы использовать OSGi в качестве стандартизованного подхода модуляции. Я думал о том, как отдельные задачи могут быть решены с помощью OSGi:

  • Статические ресурсы - пакеты OSGi, которые хотят экспортировать статические ресурсы, регистрируют экземпляры ResourceLoader с контекстом связки. Центральный ResourceServlet использует эти загрузчики ресурсов для загрузки ресурсов из пакетов.
  • Шаблоны Facelet - аналогично выше, центральная ResourceResolver использует сервисы, зарегистрированные пакетами.
  • Управляемый beans - Я понятия не имею, как использовать выражение типа #{myBean.property}, если myBean определено в одном из пакетов.
  • API-интерфейс Servlet - используйте что-то вроде WebExtender/Pax Web для регистрации сервлетов, фильтров и т.д.

Мои вопросы:

  • Я изобретаю велосипед здесь? Существуют ли для этого стандартные решения? Я нашел упоминание Spring Slices, но не смог найти много документации об этом.
  • Как вы думаете, OSGi - это правильная технология для описанной задачи?
  • Является ли мой эскиз приложения OSGI более или менее правильным?
  • Как следует обрабатывать beans (особенно область запроса/сеанса)?

Буду благодарен за ваши комментарии.

4b9b3361

Ответ 1

Что вы делаете, чтобы сделать звуки выполнимыми, с несколькими оговорками:

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

Модули сами: Во-вторых, ваши модули не кажутся особенно модульными. В вашем первом списке пули звучит так, как будто вы пытаетесь создать совместимые веб-приложения, а не модули как таковые. Мое представление о модуле состоит в том, что каждый компонент имеет четко определенную и более или менее дискретную цель. Как будто ex лежит в основе vi. Если вы идете по пути OSGi, тогда мы должны определить модульную структуру следующим образом: Модульная, ради этого обсуждения, означает, что компоненты с возможностью "горячей" замены - то есть они могут быть добавлены и удалены без нарушения приложения.

Зависимости: Я немного обеспокоен вашим описанием модулей как "возможно, в зависимости друг от друга". Вы, вероятно, знаете (я надеюсь), но ваши зависимости должны формировать ориентированный ациклический граф. Когда вы вводите круговую зависимость, вы просите мир о боли с точки зрения возможной ремонтопригодности приложения. Одной из самых слабых сторон OSGi является то, что она не предотвращает циклические зависимости, поэтому вам нужно обеспечить это. В противном случае ваши зависимости будут расти как кудзу и постепенно подавляют остальную экосистему вашей системы.

Сервлеты: Fuhgeddaboudit. Вы не можете привязать сервлеты к веб-приложению, пока не появится спецификация Servlet 3.0 (как указал Паскаль). Чтобы запустить отдельный служебный сервлет, вам нужно будет поместить его в свое приложение.


Хорошо, так много для оговорок. Подумайте, как это может работать:

Вы определили свой собственный модуль JSF, чтобы сделать... что именно? Дайте ему определенную, довольно тривиальную цель: экран входа в систему. Таким образом, вы создаете свой экран входа в систему, опоздаете с помощью OSGi в свое приложение и... тогда что? Как приложение знает, что функция входа в систему существует, если вы не определили ее на своей странице .jspx? Как приложение знает, чтобы перейти к чему-то, чего он не может знать?

Есть способы обойти это с помощью условных включений и т.д. (например, <c:if #{loginBean.notEmpty}>), но, как вы сказали, все становится немного волосатым, когда ваш управляемый loginBean существует в другом модуле, который, возможно, даже не был введен к приложению еще. Фактически, вы получите исключение сервлета, если только этот loginBean не существует. Итак, что вы делаете?

Вы определяете API в одном из своих модулей. Все управляемые beans, которые вы намерены разделить между модулями, должны быть указаны как интерфейсы в этом уровне API. И все ваши модули должны иметь стандартные реализации любого из этих интерфейсов, которые они намереваются использовать. И этот API должен быть разделен между всеми совместимыми модулями. Затем вы можете использовать OSGi и Spring для объединения указанных beans с их реализацией.

Мне нужно сделать минутку, чтобы указать, что я не буду подходить к этой проблеме. Не за что. Учитывая что-то вроде простой страницы входа в систему или даже такой сложной, как диаграмма акций, я лично предпочел бы создать пользовательский компонент JSF. Но если требование "я хочу, чтобы мой управляемый beans был модульным (т.е. С возможностью" горячей "замены и т.д.)," Это единственный способ, которым я знаю, чтобы он работал. И я даже не уверен, что он будет работать. Этот обмен по электронной почте говорит о том, что это проблема, с которой разработчики JSF только начали работать.

Я обычно считаю, что управляемый beans является частью слоя представления, и поэтому я использую их только для логики представления и делегировать все остальное на уровень сервиса. Создание управляемого beans позднего связывания - это, на мой взгляд, продвижение их из уровня представления и в бизнес-логику. Есть причина, по которой все эти учебники настолько сосредоточены на сервисах: потому что большую часть времени вы хотите рассмотреть, что потребуется для вашего приложения, чтобы запустить "без головы", и как легко было бы "скинуть" ваш взгляд, если для экземпляр, вы хотели, чтобы он запускался со всеми его функциями на телефоне Android.

Но это звучит так, как будто многое из того, с чем вы работаете, есть сама логика просмотра - например, необходимость обмена в другом шаблоне представления. OSGi/ Spring должен быть в состоянии помочь, но вам нужно что-то в вашем приложении, чтобы выбрать между доступными реализациями: практически то, что было создано для OSGi Service Registry.

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

Что касается оставшихся вопросов:

Я изобретаю здесь велосипед? Существуют ли для этого стандартные решения?

Ты, немного. Я видел приложения, которые делают такие вещи, но вы, кажется, наткнулись на довольно уникальный набор требований.

Как вы думаете, OSGi - это правильная технология для описанной задачи?

Если вам нужны модули для горячей замены, тогда ваши варианты - OSGi и более легкий интерфейс ServiceLocator.

Является ли мой эскиз приложения OSGI более-менее правильным?

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

Но не верьте мне на слово. I найдено другой материал для чтения в этих местах.

А так как вы спрашиваете о Spring Slices, этого должно быть достаточно, чтобы вы начали. Вам понадобится клиент Git, и похоже, что вы будете тренироваться самостоятельно, просматривая исходный код. И это очень ранний прототип кода.

Ответ 2

Я сталкиваюсь с теми же проблемами в моем текущем проекте. На мой взгляд, OSGi - лучшее и чистое решение с точки зрения стандартов и будущей поддержки, но в настоящее время вы можете столкнуться с некоторыми проблемами, если попытаетесь использовать его в веб-приложении:

  • пока нет хорошо интегрированного решения между веб-контейнером и платформой OSGi.
  • OSGi может быть слишком большой для веб-приложения пользовательской сборки, которое просто ищет простую модульную архитектуру. Я бы рассмотрел OSGi, если мой проект должен поддерживать сторонние расширения, которые не находятся под нашим контролем на 100%, если проекту нужны горячие повторные развертывания, строгие правила доступа между плагинами и т.д.

Пользовательское решение, основанное на загрузчиках классов и фильтрах ресурсов, кажется мне очень подходящим. В качестве примера вы можете изучить исходный код Хадсона или проект Java Plug-in Framework (JPF) (http://jpf.sourceforge.net/)).

Как о расширении web.xml, нам может быть повезло с спецификацией Servlet 3.0 (http://today.java.net/pub/a/today/2008/10/14/introduction-to-servlet-3.html # pluggability-и-расширяемость).

Ответ 3

Здесь будет приятным "фрагмент дескриптора развертывания веб-модуля" (aka web-fragment.xml), представленный спецификацией Servlet 3.0. Спецификация определяет его как:

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

Java EE 6, возможно, не вариант для вас прямо сейчас. Тем не менее, это будет стандартизованное решение.

Ответ 4

Enterprise OSGi - довольно новый домен, поэтому не думайте, что получите решение, которое удовлетворит ваши потребности. Тем не менее, одна из вещей, которые я нашел отсутствующими в Equinox (osgi engine за затмением и, следовательно, одна с самой большой базой пользователей!), Является последовательной конфигурацией/DI-службой. В моем проекте в последнее время у нас были некоторые аналогичные потребности, и он завершил создание простой службы osgi конфигурации.

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

Помимо конфигурации, вы можете взглянуть на недавно выпущенную книгу Equinox для руководства по использованию OSGi в качестве базы для создания модульных приложений. Примеры могут быть специфическими для Equinox, но принципы будут работать с любой платформой OSGi. Ссылка - http://equinoxosgi.org/

Ответ 5

Вы должны заглянуть в Spring DM Server (он перешел на Eclipse Virgo, но еще не был выпущен). В недавнем выпуске OSGi Enterprise есть много хороших вещей, которые также были выпущены.

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

Что касается контекста сеанса - он обрабатывается так, как вы ожидали бы в сеансе. Однако у вас могут возникнуть проблемы с совместным использованием этого сеанса между веб-пакетами до такой степени, что он не уверен, что это возможно.

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