Давайте расскажем об основанных на Java архитектурах веб-приложений!
Для веб-приложений существует множество различных архитектур, которые должны быть реализованы с использованием Java. Ответами на этот вопрос могут служить библиотеки различных дизайнов веб-приложений со своими плюсами и минусами. Хотя я понимаю, что ответы будут субъективными, давайте постараемся быть максимально объективными и мотивировать перечисленные плюсы и минусы.
Используйте уровень детализации, который вы предпочитаете для описания вашей архитектуры. Чтобы ваш ответ имел какую-либо ценность, вам, по крайней мере, придется описать основные технологии и идеи, используемые в описываемой вами архитектуре. И последнее, но не менее важное, когда мы должны использовать вашу архитектуру?
Я начну...
Обзор архитектуры
Мы используем трехуровневую архитектуру, основанную на открытых стандартах Sun, таких как Java EE, Java Persistence API, Servlet и Java Server Pages.
- Упорство
- Бизнес
- презентация
Возможные коммуникационные потоки между уровнями представлены:
Persistence <-> Business <-> Presentation
Что, например, означает, что уровень представления никогда не вызывает и не выполняет операции персистентности, он всегда делает это через бизнес-уровень. Эта архитектура предназначена для удовлетворения требований веб-приложения высокой доступности.
Упорство
Выполняет операции сохранения , чтения, обновления и удаления ( CRUD ). В нашем случае мы используем ( Java Persistence API ) JPA, и в настоящее время мы используем Hibernate в качестве нашего поставщика сохраняемости и используем его EntityManager .
Этот уровень разделен на несколько классов, где каждый класс имеет дело с определенным типом сущностей (то есть сущности, связанные с корзиной покупок, могут обрабатываться одним классом постоянства) и используется одним и только одним менеджером .
Кроме того, в этом слое также хранятся объекты JPA , такие как Account
и ShoppingCart
т. Д.
Бизнес
Вся логика, которая связана с функциональностью веб-приложения, находится на этом уровне. Эта функция может инициировать перевод денег для клиента, который хочет оплатить продукт в режиме онлайн с помощью своей кредитной карты. С таким же успехом это может быть создание нового пользователя, удаление пользователя или вычисление исхода битвы в сетевой игре.
Этот уровень разделен на несколько классов, и каждый из этих классов помечается, @Stateless
чтобы стать компонентом сеанса без сохранения состояния (SLSB). Каждый SLSB называется менеджером, и, например, менеджер может быть аннотированным классом, как указано выше AccountManager
.
Когда AccountManager
необходимо выполнить операции CRUD, он делает соответствующие вызовы экземпляру класса AccountManagerPersistence
, который является постоянным уровнем. Примерный набросок двух методов AccountManager
может быть:
...
public void makeExpiredAccountsInactive() {
AccountManagerPersistence amp = new AccountManagerPersistence(...)
// Calls persistence layer
List<Account> expiredAccounts = amp.getAllExpiredAccounts();
for(Account account : expiredAccounts) {
this.makeAccountInactive(account)
}
}
public void makeAccountInactive(Account account) {
AccountManagerPersistence amp = new AccountManagerPersistence(...)
account.deactivate();
amp.storeUpdatedAccount(account); // Calls persistence layer
}
Мы используем транзакции диспетчера контейнеров, поэтому нам не нужно проводить разграничение транзакций самостоятельно. В сущности, что происходит внутри, мы инициируем транзакцию при входе в метод SLSB и фиксируем ее (или выполняем откат) непосредственно перед выходом из метода. Это пример соглашения по конфигурации, но нам пока что не нужно ничего, кроме значения по умолчанию, Требуется.
Вот как в руководстве по Java EE 5 от Sun объясняется обязательный атрибут транзакции для Enterprise JavaBeans (EJB):
Если клиент работает в транзакции и вызывает метод корпоративного компонента, метод выполняется в транзакции клиента. Если клиент не связан с транзакцией, контейнер запускает новую транзакцию перед запуском метода.
Атрибут Required является неявным атрибутом транзакции для всех методов корпоративного компонента, работающих с разграничением транзакций, управляемым контейнером. Обычно вы не устанавливаете атрибут Required, если вам не нужно переопределять другой атрибут транзакции. Поскольку атрибуты транзакции являются декларативными, вы можете легко изменить их позже.
презентация
Наш уровень представления отвечает за ... представление! Он отвечает за пользовательский интерфейс и показывает информацию пользователю, создавая HTML-страницы и получая пользовательский ввод через запросы GET и POST. В настоящее время мы используем старую комбинацию Servlet + Java Server Pages ( JSP ).
Уровень вызывает методы в менеджерах бизнес-уровня для выполнения операций, запрошенных пользователем, и получения информации для отображения на веб-странице. Иногда информация, полученная от бизнес-уровня, представляет собой менее сложные типы, такие как String
s и int
egers, а в других случаях объекты JPA .
Плюсы и минусы с архитектурой
Pros
- Наличие всего, что связано с определенным способом сохранения в этом слое, означает только то, что мы можем перейти от использования JPA к чему-то другому, без необходимости что-либо переписывать на бизнес-уровне.
- Нам легко поменять наш уровень презентации на что-то другое, и, скорее всего, мы это сделаем, если найдем что-то лучшее.
- Позволить контейнеру EJB управлять границами транзакций - это хорошо.
- Использовать Servlet + JPA легко (для начала), а технологии широко используются и применяются на многих серверах.
- Предполагается, что использование Java EE облегчит нам создание системы высокой доступности с балансировкой нагрузки и переключением при сбое . Оба из которых мы чувствуем, что мы должны иметь.
Cons
- Используя JPA, вы можете хранить часто используемые запросы как именованные запросы, используя
@NamedQuery
аннотацию к классу сущностей JPA. Если у вас как можно больше связано с постоянством в классах постоянства, как в нашей архитектуре, это будет распространяться на места, где вы можете также найти запросы для включения сущностей JPA. Будет сложнее рассмотреть операции сохранения и, следовательно, сложнее поддерживать. - У нас есть сущности JPA как часть нашего уровня постоянства. Но
Account
иShoppingCart
разве они не являются бизнес-объектами? Это делается так, как вы должны прикоснуться к этим классам и превратить их в сущности, с которыми JPA знает, как обращаться. - Объекты JPA, которые также являются нашими бизнес-объектами, создаются как объекты передачи данных ( DTO ), также известные как объекты значений (VO). Это приводит к анемичной модели предметной области, поскольку у бизнес-объектов нет собственной логики, кроме методов доступа. Вся логика выполняется нашими менеджерами на бизнес-уровне, что приводит к более процедурному стилю программирования. Это не хороший объектно-ориентированный дизайн, но, может быть, это не проблема? (В конце концов, объектная ориентация - не единственная парадигма программирования, которая дала результаты.)
- Использование EJB и Java EE представляет некоторую сложность. И мы не можем использовать чисто Tomcat (добавление EJB-микроконтейнера - это не просто Tomcat).
- Есть много проблем с использованием Servlet's + JPA. Используйте Google для получения дополнительной информации об этих проблемах.
- Поскольку транзакции закрываются при выходе из бизнес-уровня, мы не можем загрузить любую информацию из сущностей JPA, которая настроена для загрузки из базы данных, когда она необходима (используется
fetch=FetchType.LAZY
), из уровня представления. Это вызовет исключение. Перед возвратом объекта, содержащего поля такого типа, мы должны обязательно вызвать соответствующий получатель. Другой вариант - использовать язык запросов постоянства Java ( JPQL ) и выполнить команду aFETCH JOIN
. Однако оба эти варианта немного громоздки.
источник
Ответы:
Хорошо, я сделаю (короче) один:
Мы используем поддержку транзакций Sping и запускаем транзакции при входе на уровень обслуживания, распространяясь до вызовов DAO. Уровень обслуживания обладает большинством бизнес-моделей, а DAO выполняет относительно простую работу CRUD.
Некоторые более сложные запросы обрабатываются более сложными запросами в бэкэнде по соображениям производительности.
Преимущества использования Spring в нашем случае состоят в том, что у нас могут быть зависящие от страны / языка экземпляры, которые находятся за классом Spring Proxy. Исходя из пользователя в сеансе, правильная реализация страны / языка используется при выполнении вызова.
Управление транзакциями практически прозрачно, откат исключений во время выполнения. Мы используем непроверенные исключения в максимально возможной степени. Раньше мы делали проверенные исключения, но с появлением Spring я вижу преимущества непроверенных исключений, обрабатывая исключения только тогда, когда это возможно. Это позволяет избежать множества «ловить / отбрасывать» или «бросать» вещи.
Извините, это короче, чем ваш пост, надеюсь, вы найдете это интересным ...
источник
Идеальные Java-технологии для веб-разработки сегодня.
Веб-слой:
HTML + CSS + Ajax + JQuery
RESTFul веб-контроллер / действие / уровень обработки запросов:
Play Framework
Бизнес-логика / сервисный уровень:
Используйте Pure Java Code как можно дольше. Здесь можно объединить веб-сервисы.
Уровень преобразования данных XML / JSon:
XMLTool (поиск по коду Google), JSoup, Google GSon, XStream, JOOX (поиск по коду Google)
Слой постоянства:
CRUD: JPA или SienaProject или QueryDSL / сложные запросы: JOOQ, QueryDSL
источник
Вот мои 5 центов
презентация
Android, Angular.JS WebClient, OAUTHv2
API
REST, Джерси (JAX-RS), Джексон (JSON-де-сериализация), DTO-объекты (отличные от моделей бизнес-логики)
Бизнес Логика
Spring для DI и обработки событий. DDD-подход подхода модельных объектов. Более длинные рабочие задания выгружаются с SQS в рабочие модули.
DAO
Модель репозитория с Spring JDBC-шаблонами для хранения сущностей. Redis (JEDIS) для списков лидеров, используя упорядоченные списки. Memcache для магазина токенов.
База данных
MySQL, Memcached, Redis
источник
То, что мы следовали в нашем проекте:
Front end Technology
API
Бизнес Логика
Весенние данные
ВЕСНА данных MongoDB
База данных
Сервер (для кеширования)
источник
Мы все еще используем обычный стек Struts-Spring-Hibernate.
Для будущих приложений мы ищем Spring Web Flow + Spring MVC + Hibernate или Spring + Hibernate + Web Services с интерфейсом Flex.
Отличительной чертой нашей архитектуры является модульность. У нас есть несколько модулей, некоторые из которых начинаются с 3 до 30 таблиц в базе данных. Большинство модулей состоит из бизнеса и веб-проекта. Бизнес-проект содержит логику ведения бизнеса и настойчивости, а сеть - логику представления.
На логическом уровне существует три уровня: бизнес, постоянство и презентация.
Зависимости:
презентация зависит от бизнеса и настойчивости.
Постоянство зависит от бизнеса.
Бизнес не зависит от других слоев.
Большинство бизнес-проектов имеют три типа интерфейсов (примечание: не GUI, это программный уровень интерфейса Java).
Часто 1 расширяется 2. Таким образом, одну реализацию модуля легко заменить другой. Это помогает нам адаптироваться к различным клиентам и легче интегрироваться. Некоторые клиенты будут покупать только определенные модули, и нам нужно интегрировать функциональность, которая у них уже есть. Поскольку интерфейс и уровень реализации разделены, легко развернуть реализацию модуля ad-hock для этого конкретного клиента, не затрагивая зависимые модули. А Spring Framework позволяет легко внедрять различные реализации.
Наш бизнес уровень основан на POJO. Я наблюдаю одну тенденцию - эти POJO напоминают DTO. Мы страдаем от анемичной доменной модели . Я не совсем уверен, почему это происходит, но это может быть связано с простотой проблемной области многих наших модулей, большая часть работы - CRUD или из-за разработчиков, предпочитающих размещать логику где-то еще.
источник
Вот еще одна веб-архитектура, над которой я работал:
Уровень презентации:
Мобильный Интернет (HTML5 / CSS3 / Адаптивный дизайн)
Spring REST Controllers (Может измениться на JAX-RS)
Уровень бизнес-услуг:
Spring @Service (может измениться на EJB без сохранения состояния)
Уровень доступа к данным:
Spring @Repository (Может измениться на EJB без сохранения состояния)
Уровень ресурса:
Объекты гибернации (JPA) (можно изменить на любой ORM)
Вы можете найти больше информации о книге, которая следует этой архитектуре здесь .
источник
ИМХО, у большинства из нас есть общий знаменатель. По крайней мере, у нас есть некоторая форма контейнера IOC / DI и структура персистентности. Лично я использую Guice и Mybatis для этого. Различия заключаются в том, как мы реализуем уровень представления / пользовательского интерфейса / представления. Здесь есть 2 основных варианта (может быть и больше). На основе действий (URL-адреса сопоставлены с контроллерами) и на основе компонентов. В настоящее время я использую компонентный слой представления (используя wicket). Он отлично имитирует среду рабочего стола, где я использую компоненты и события, а не URL-адреса и контроллеры. В настоящее время я ищу причину, по которой мне следует перейти на архитектуру такого рода URL-контроллера (именно так я и оказался на этой странице). Почему шумиха о RESTful и архитектурах без состояния.
Чтобы ответить на этот вопрос вкратце: я пишу веб-приложения с сохранением состояния с использованием компонентно-ориентированной среды поверх контейнера Guice IOC и помещаю данные в реляционную базу данных с помощью Mybatis.
источник
Немного по-другому, и я бы сказал, что здесь более модульная архитектура Java. У нас есть:
В дополнение к вышесказанному у нас есть модули с общей библиотекой, которая является поставщиком общих функций для всех сервисов.
Использование разных слоев позволяет нам полностью отделить и модульность, в которой мы нуждаемся. Мы также можем в полной мере использовать возможности Java EE и Spring. Ничто не мешает нам использовать JSF, например, для внешнего интерфейса, если это необходимо.
По сравнению с примером архитектуры от OP, я думаю, что это можно описать как наличие четырех основных слоев вместо трех, хотя и с изюминкой.
источник
Я работал над проектами, которые используют этот жесткий шаблон менеджера. Исторически я был большим сторонником жесткой иерархии, где все укладывалось в аккуратную коробку. По мере того, как я продвигаюсь в своей карьере, я нахожу это вынужденным во многих случаях. Я считаю, что принятие более гибкого подхода к разработке приложений ведет к созданию лучшего продукта. Что я имею в виду под созданием набора классов, которые решают проблему под рукой. Вместо того, чтобы говорить "Вы построили менеджера для этого и того?"
Текущий проект, над которым я работаю, - это веб-приложение с комбинацией вызовов Spring MVC и RestEasy JSON / Ajax. На стороне сервера в наши контроллеры встроен разумный уровень данных на основе фасадов с JPA / Hibernate для прямого доступа к базе данных, некоторого доступа к EJB и некоторых вызовов веб-служб на основе SOAP. Связывание всего этого - некоторый пользовательский код контроллера Java, который определяет, что сериализовать как JSON и вернуть клиенту.
Мы почти не тратим время на попытки создать какой-то унифицированный шаблон, вместо этого выбирая идею «хуже - лучше» философии дизайна Unix. Поскольку гораздо лучше выделять цвета за пределы линий и создавать что-то разумное, быстрее, чем создавать что-то, соответствующее строгим требованиям дизайна.
источник
Компоненты в архитектуре веб-приложений включают в себя:
1: Браузер: взаимодействие с клиентом
2: Интернет
3: веб-сервер
4: Сервер приложений
5: Сервер базы данных
6: Данные
источник