Как модульизировать приложение JSF / Facelets / Spring с помощью OSGi?
Я работаю с очень большими приложениями JSF / Facelets, которые используют Spring для управления DI/bean. Мои приложения имеют модульную структуру, и в настоящее время я ищу подходы к стандартизации модульности.
моя цель-создать веб-приложение из нескольких модулей (возможно, в зависимости друг от друга). Каждый модуль может содержать следующее:
- обучение;
- статические ресурсы (изображения, CSS, скрипты);
- шаблоны экземпляры facelet;
- управляемые бобы-контексты приложений Spring с запросами, сеансами и областью применения (альтернативой являются управляемые бобы JSF);
- Servlet API stuff-сервлеты, фильтры, слушатели (это необязательно).
чего я хотел бы избежать (почти любой ценой), так это необходимости копировать или извлекать ресурсы модуля (например, шаблоны Facelets) на войну или расширять web.xml
для сервлетов модуля , фильтров и т. д. Должно быть достаточно добавить модуль (JAR, bundle, artifact,...) в веб-приложение (WEB-INF/lib
, bundles
, plugins
, ...) для расширения веб-приложения с помощью этого модуля.
в данный момент я решаю эту задачу с помощью пользовательских решений модульность, которая в значительной степени основывается на использовании ресурсы classpath:
- сервлет специальных ресурсов обслуживает статические ресурсы из ресурсов пути к классам (JARs).
- специальный решатель ресурсов Facelets позволяет загрузка шаблонов фасетов из ресурсов classpath.
- Spring загружает контексты приложений через шаблон
classpath*:com/acme/foo/module/applicationContext.xml
- это загружает контексты приложений, определенные в банках модулей. - наконец, пара делегирующих сервлетов и фильтров делегирует обработку запросов сервлетам и фильтрам, настроенным в контекстах приложений Spring из модулей.
в последние дни я много читал об OSGi, и я рассматривал, как (и если) я мог бы использовать OSGi в качестве стандартизированный модульный подход. Я думал о том, как отдельные задачи могут быть решены с помощью OSGi:
- статические ресурсы-пакеты OSGi, которые хотят экспортировать статические ресурсы, регистрируют
ResourceLoader
экземпляры с контекстом пакета. ЦентральныйResourceServlet
использует эти загрузчики ресурсов для загрузки ресурсов из пачки. - Шаблоны Facelet-аналогично выше, центральный
ResourceResolver
использует сервисы, зарегистрированные пакетами. - управляемые бобы - I понятия не имею!--49--> как использовать выражение типа
#{myBean.property}
еслиmyBean
определяется в одном из пакетов. - Servlet API stuff-используйте что-то вроде WebExtender/Pax Web для регистрации сервлетов, фильтров и так далее.
мои вопросы:
- я изобретаю велосипед? Существуют ли стандартные решения для этого? Я нашел упоминание о весенних срезах, но не смог найти много документации об этом.
- вы думаете, OSGi-правильная технология для описанной задачи?
- является ли мой эскиз приложения OSGI более или менее правильным?
- как следует обрабатывать управляемые компоненты (особенно область запроса/сеанса)?
Я бы вообще благодарен за ваши комментарии.
5 ответов
то, что вы собираетесь сделать, звучит выполнимо, с несколькими оговорками:
Вид Слоя: во-первых, ваш слой просмотра звучит немного переполненным. Есть и другие способы модульизации компонентов JSF с помощью пользовательских компонентов, которые позволят избежать головной боли при попытке создать что-то столь же драматичное, как управляемые бобы с поздним связыванием.
Сами Модули: во-вторых, ваши модули не очень модульный. Ваш первый список звучит так, как будто вы пытаетесь создать совместимые веб-приложения, а не модули как таковые. Моя идея модуля заключается в том, что каждый компонент имеет четко определенную и более или менее дискретную цель. Как ex лежит vi. Если вы идете по маршруту OSGi, то мы должны определить модульный следующим образом:модульный, ради этого обсуждения, означает, что компоненты могут быть заменены горячей заменой - то есть они могут быть добавлены и удалены без нарушения приложение.
зависимости: меня немного беспокоит ваше описание модулей как " возможно, в зависимости друг от друга."Вы, вероятно (я надеюсь), уже знаете это, но ваши зависимости должны сформировать направленный ациклический граф. Как только вы вводите циклическую зависимость, вы просите мир боли с точки зрения возможной ремонтопригодности приложения. Одним из самых больших недостатков OSGi является то, что он не предотвращение круговых зависимостей, поэтому это зависит от вас, чтобы обеспечить это. В противном случае ваши зависимости будут расти, как кудзу, и постепенно задушат остальную экосистему вашей системы.
сервлеты: Fuhgeddaboudit. Вы не можете поздно связывать сервлеты в веб-приложение, пока спецификация сервлета 3.0 не будет запущена (как указал Паскаль). Чтобы запустить отдельный служебный сервлет, вам нужно поместить его в собственное приложение.
ок, спасибо за сноску. Давайте подумаем, как это может работа:
вы определили свой собственный модуль JSF... что именно? Давайте дадим ему определенную, довольно тривиальную цель: экран входа в систему. Таким образом, вы создаете экран входа в систему, поздно связываете его с помощью OSGi в свое приложение и... а что потом? Как приложение знает функциональность входа в систему, если вы не определили ее в своем.страница jspx успешно? Как приложение знает, чтобы перейти к чему-то, что он не может знать, есть?
есть способы обойти это, используя условные includes и как (например, <c:if #{loginBean.notEmpty}>
), но, как вы сказали, все становится немного волосатым, когда ваш управляемый loginBean существует в другом модуле, который, возможно, еще даже не был введен в приложение. Фактически, вы получите исключение сервлета, если этот loginBean не существует. Так что ты делаешь?
вы определяете API в одном из ваших модулей. все управляемые компоненты, которые вы собираетесь совместно использовать между модулями, должны быть указаны в качестве интерфейсов на этом уровне API. И все ваши модули должны иметь значение по умолчанию реализации любой из этих интерфейсов, которые они намерены использовать. И этот API должен быть разделен между всеми совместимыми модулями. Затем вы можете использовать OSGi и Spring для связывания указанных бобов с их реализацией.
мне нужно воспользоваться моментом, чтобы указать, что это не так, как я бы подошел к этой проблеме. Нисколько. Учитывая что-то вроде простой страницы входа в систему или даже такой же сложный, как график акций, я лично предпочел бы создать пользовательский JSF деталь. Но если требование "я хочу, чтобы мои управляемые бобы были модульными (т. е. с возможностью горячей замены и т. д.)", Это единственный способ заставить его работать. И я даже не совсем уверен в этом!--4-->будет работа. этот обмен электронной почтой предполагает, что это проблема, над которой разработчики JSF только начали работать.
Я обычно считаю управляемые бобы частью слоя представления, и поэтому я использую их только для логики представления и делегирую все остальное на уровень сервиса. Создание управляемых бобов с задержкой привязки, на мой взгляд, продвигает их из слоя просмотра и в бизнес-логику. Есть причина, по которой все эти учебники так сосредоточены на услугах: потому что большую часть времени вы хотите рассмотреть, что потребуется для вашего приложения, чтобы запустить "безголовый", и как легко было бы "снять кожу" с Вашего взгляда, если, например, вы хотите, чтобы он работал со всеми его функциями на телефоне Android.
но это звучит, как много, что вы работа с самой логикой представления - например, необходимость замены в другом шаблоне представления. OSGi / Spring должен быть в состоянии помочь, но вам понадобится что-то в вашем приложении, чтобы выбрать между доступными реализациями: в значительной степени то, для чего был создан реестр служб OSGi.
это оставляет статические ресурсы. Вы можете распределить эти, но помните, что вам потребуется, чтобы определить интерфейс для извлечения этих ресурсов, и вам необходимо обеспечить реализацию по умолчанию, так что ваше приложение не подавитесь, если их нет. Если i18n это внимание, это может быть хорошим способом пойти. Если вы хотите быть действительно авантюрный, тогда вы можете подтолкнуть свои статические ресурсы в JNDI. Это сделает их полностью горячей заменой и избавит вас от необходимости пытаться решить, какую реализацию использовать программно, но есть некоторые недостатки: любой неудачный поиск приведет к тому, что ваше приложение выдаст исключение NamingException. И это перебор. JNDI обычно используется в веб-приложениях для приложений конфигурация.
что касается оставшихся вопросов:
я изобретаю велосипед? Существуют ли стандартные решения для этого?
вы, немного. Я видел приложения, которые делают это вид вещи, но вы, кажется, наткнулись на довольно уникальный набор требований.
считаете ли вы, что OSGi является правильной технологией для описанной задачи?
Если вам нужны модули горячая замена, то ваш выбор OSGi и более легкий интерфейс ServiceLocator.
является ли мой эскиз приложения OSGI более или менее правильным?
Я не могу сказать, не зная больше о том, где ваши границы компонента. На данный момент кажется, что вы можете подтолкнуть OSGi сделать больше, чем он способен сделать.
я нашел другое чтение материала в этих местах.и так как вы спрашиваете о Spring Slices,этого должно быть достаточно, чтобы вы начали. Вам понадобится клиент Git, и похоже, что вы будете тренироваться в приложении, просматривая исходный код. И это очень ранний прототип кода.
Я сталкиваются с теми же проблемами в моем текущем проекте. На мой взгляд, OSGi-лучшее и самое чистое решение с точки зрения стандартов и будущей поддержки, но в настоящее время вы можете столкнуться с некоторыми проблемами, если попытаетесь использовать его в веб-приложении:
- пока нет хорошо интегрированного решения между веб-контейнером и платформой OSGi.
- OSGi может быть слишком много для пользовательского веб-приложения сборки, которое просто ищет простую модульную архитектуру. Я бы рассмотрим OSGi, если мой проект должен поддерживать сторонние расширения, которые не находятся на 100% под нашим контролем,если проект нуждается в горячих перераспределениях, строгих правилах доступа между плагинами и т. д.
пользовательское решение, основанное на загрузчиках классов и фильтрах ресурсов, кажется мне очень подходящим. В качестве примера вы можете изучить исходный код Хадсона или проект Java Plug-In Framework (JPF) (http://jpf.sourceforge.net/).
как о расширении сети.XML, мы можем повезло с сервлетом 3.0 specification(http://today.java.net/pub/a/today/2008/10/14/introduction-to-servlet-3.html#pluggability-and-extensibility).
"фрагмент дескриптора развертывания веб-модуля" (он же веб-фрагмент.xml) введенный сервлет 3.0 спецификация было бы хорошо здесь. Спецификация определяет его как:
веб-фрагмент является логическим разбиение веб-приложения на разделы так что рамки используется в веб-приложении можно определить все артефакты, не спрашивая devlopers изменить или добавить информацию в сеть.XML.
Java EE 6 возможно не вариант для вас прямо сейчас. И все же это будет стандартное решение.
Enterprise OSGi-довольно новый домен, поэтому не думайте, что вы получите решение, которое непосредственно удовлетворит ваши потребности. Это сказало одну из вещей, которые я нашел отсутствующими в Equinox (OSGi engine за eclipse и, следовательно, с самой большой базой пользователей!) является последовательной конфигурацией / службой DI. В моем проекте недавно у нас были некоторые аналогичные потребности и закончилось создание простой конфигурации службы osgi.
одна из проблем, которая будет присуща модульным приложениям, будет вокруг DI, поскольку видимость модуля может в некоторых случаях препятствовать доступу к классу. Мы обошли это, используя политику зарегистрированного приятеля, которая не слишком идеальна, но работает.
кроме конфигурации, вы можете взглянуть на недавно выпущенную книгу Equinox для руководства по использованию OSGi в качестве основы для создания модульных приложений. Примеры могут быть специфичными для Equinox, но принципы будут работать с любой структурой OSGi. Ссылка - http://equinoxosgi.org/
вы должны посмотреть на сервер Spring DM (он переходит на Eclipse Virgo, но он еще не выпущен). В недавней спецификации OSGi enterprise, которая также только что была выпущена, есть много хороших вещей.
некоторые из весенних учебников DM помогут, я бы предположил. Но да, можно иметь как ресурсы, так и классы, загруженные извне веб-пакета, используя стандартную модульность. В этом, это хорошо подходит.
Что касается контекста сеанса-он получает обрабатывается так, как вы ожидаете на сеансе. Однако вы можете столкнуться с проблемами при совместном использовании этого сеанса между веб-пакетами в такой степени, что даже не уверены, возможно ли это.
вы также можете иметь один веб-пакет, а затем использовать, например, реестр расширения Eclipse для расширения возможностей вашего веб-приложения.