Опишите архитектуру, которую вы используете для веб-приложений Java? [закрыто]


146

Давайте расскажем об основанных на 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 ).

Уровень вызывает методы в менеджерах бизнес-уровня для выполнения операций, запрошенных пользователем, и получения информации для отображения на веб-странице. Иногда информация, полученная от бизнес-уровня, представляет собой менее сложные типы, такие как Strings и integers, а в других случаях объекты 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 ) и выполнить команду a FETCH JOIN. Однако оба эти варианта немного громоздки.

1
Кажется, вы поставили планку слишком высоко своим собственным ответом - это, возможно, обескуражило других :)
Jonik

5
Кроме того, возможно, ваш ответ должен быть обычным ответом, а не частью вопроса, чтобы за него проголосовали наряду с другими ответами?
Джоник

Этот вопрос был упомянут на мета.
D4V1D

Ответы:


20

Хорошо, я сделаю (короче) один:

  • Frontend: Tapestry (3 для старых проектов, 5 для новых)
  • Бизнес уровень: Весна
  • ДАО: Ибатис
  • База данных: Oracle

Мы используем поддержку транзакций Sping и запускаем транзакции при входе на уровень обслуживания, распространяясь до вызовов DAO. Уровень обслуживания обладает большинством бизнес-моделей, а DAO выполняет относительно простую работу CRUD.

Некоторые более сложные запросы обрабатываются более сложными запросами в бэкэнде по соображениям производительности.

Преимущества использования Spring в нашем случае состоят в том, что у нас могут быть зависящие от страны / языка экземпляры, которые находятся за классом Spring Proxy. Исходя из пользователя в сеансе, правильная реализация страны / языка используется при выполнении вызова.

Управление транзакциями практически прозрачно, откат исключений во время выполнения. Мы используем непроверенные исключения в максимально возможной степени. Раньше мы делали проверенные исключения, но с появлением Spring я вижу преимущества непроверенных исключений, обрабатывая исключения только тогда, когда это возможно. Это позволяет избежать множества «ловить / отбрасывать» или «бросать» вещи.

Извините, это короче, чем ваш пост, надеюсь, вы найдете это интересным ...


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

19

Идеальные 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


9

Вот мои 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


Это похоже на то, что мы делаем в наших проектах! Кроме того, JBPM для бизнес-процессов. Почему нет весны интересно?
Ininprsr

Я должен сделать обновление с нашей текущей аркой: в настоящее время мы используем Spring DI и JDBC-шаблоны для уровня доступа к данным.
Pepster

6

То, что мы следовали в нашем проекте:

Front end Technology

  • AngularJS
  • HTML5
  • CSS3
  • Javascript
  • Bootstrap 3

API

  1. ОСТАЛЬНОЕ
  2. Джерси (JAX-RS)
  3. БУДЬТЕ УВЕРЕНЫ
  4. Весенняя обувь
  5. Джексон
  6. весенняя безопасность

Бизнес Логика

  • Весенние данные

  • ВЕСНА данных MongoDB

База данных

  • MongoDB

Сервер (для кеширования)

  • Redis

4

Мы все еще используем обычный стек Struts-Spring-Hibernate.

Для будущих приложений мы ищем Spring Web Flow + Spring MVC + Hibernate или Spring + Hibernate + Web Services с интерфейсом Flex.

Отличительной чертой нашей архитектуры является модульность. У нас есть несколько модулей, некоторые из которых начинаются с 3 до 30 таблиц в базе данных. Большинство модулей состоит из бизнеса и веб-проекта. Бизнес-проект содержит логику ведения бизнеса и настойчивости, а сеть - логику представления.
На логическом уровне существует три уровня: бизнес, постоянство и презентация.
Зависимости:
презентация зависит от бизнеса и настойчивости.
Постоянство зависит от бизнеса.
Бизнес не зависит от других слоев.

Большинство бизнес-проектов имеют три типа интерфейсов (примечание: не GUI, это программный уровень интерфейса Java).

  1. Интерфейс, который презентация использует в качестве клиента
  2. Интерфейс, который используют другие модули, когда они являются клиентом модуля.
  3. Интерфейс, который можно использовать для административных целей модуля.

Часто 1 расширяется 2. Таким образом, одну реализацию модуля легко заменить другой. Это помогает нам адаптироваться к различным клиентам и легче интегрироваться. Некоторые клиенты будут покупать только определенные модули, и нам нужно интегрировать функциональность, которая у них уже есть. Поскольку интерфейс и уровень реализации разделены, легко развернуть реализацию модуля ad-hock для этого конкретного клиента, не затрагивая зависимые модули. А Spring Framework позволяет легко внедрять различные реализации.

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


3

Вот еще одна веб-архитектура, над которой я работал:

Одним из основных требований было приложение должно поддерживать мобильные / другие устройства. Приложение также должно быть расширяемым или гибким для изменений в выборе технологий.

Уровень презентации:

  • JSP / JQuery (MVC на стороне клиента)
  • Родной андроид
  • Родной айфон
  • Мобильный Интернет (HTML5 / CSS3 / Адаптивный дизайн)

  • Spring REST Controllers (Может измениться на JAX-RS)

Уровень бизнес-услуг:

Spring @Service (может измениться на EJB без сохранения состояния)

Уровень доступа к данным:

Spring @Repository (Может измениться на EJB без сохранения состояния)

Уровень ресурса:

Объекты гибернации (JPA) (можно изменить на любой ORM)

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


2

ИМХО, у большинства из нас есть общий знаменатель. По крайней мере, у нас есть некоторая форма контейнера IOC / DI и структура персистентности. Лично я использую Guice и Mybatis для этого. Различия заключаются в том, как мы реализуем уровень представления / пользовательского интерфейса / представления. Здесь есть 2 основных варианта (может быть и больше). На основе действий (URL-адреса сопоставлены с контроллерами) и на основе компонентов. В настоящее время я использую компонентный слой представления (используя wicket). Он отлично имитирует среду рабочего стола, где я использую компоненты и события, а не URL-адреса и контроллеры. В настоящее время я ищу причину, по которой мне следует перейти на архитектуру такого рода URL-контроллера (именно так я и оказался на этой странице). Почему шумиха о RESTful и архитектурах без состояния.

Чтобы ответить на этот вопрос вкратце: я пишу веб-приложения с сохранением состояния с использованием компонентно-ориентированной среды поверх контейнера Guice IOC и помещаю данные в реляционную базу данных с помощью Mybatis.


1

Немного по-другому, и я бы сказал, что здесь более модульная архитектура Java. У нас есть:

  1. Spring WS / Rest / JSP front end
  2. Spring MVC для логики бизнес-сервисов, содержащей логику уровня представления и транзакции Spring
  3. Компонентный сервисный интерфейс связи, просмотренный через EJB бизнес-сервисами. EJB-компоненты устанавливают собственные границы транзакций, которые могут присоединяться к транзакциям Spring.
  4. Реализации сервисов компонентов, опять же компоненты Spring
  5. Уровень интеграции, MyBatis для интеграции баз данных, Spring WS для интеграции веб-сервисов, другие технологии интеграции для других сервисов
  6. Мэйнфреймы, базы данных, другие сервисы на других серверах ...

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

Использование разных слоев позволяет нам полностью отделить и модульность, в которой мы нуждаемся. Мы также можем в полной мере использовать возможности Java EE и Spring. Ничто не мешает нам использовать JSF, например, для внешнего интерфейса, если это необходимо.

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


0

Я работал над проектами, которые используют этот жесткий шаблон менеджера. Исторически я был большим сторонником жесткой иерархии, где все укладывалось в аккуратную коробку. По мере того, как я продвигаюсь в своей карьере, я нахожу это вынужденным во многих случаях. Я считаю, что принятие более гибкого подхода к разработке приложений ведет к созданию лучшего продукта. Что я имею в виду под созданием набора классов, которые решают проблему под рукой. Вместо того, чтобы говорить "Вы построили менеджера для этого и того?"

Текущий проект, над которым я работаю, - это веб-приложение с комбинацией вызовов Spring MVC и RestEasy JSON / Ajax. На стороне сервера в наши контроллеры встроен разумный уровень данных на основе фасадов с JPA / Hibernate для прямого доступа к базе данных, некоторого доступа к EJB и некоторых вызовов веб-служб на основе SOAP. Связывание всего этого - некоторый пользовательский код контроллера Java, который определяет, что сериализовать как JSON и вернуть клиенту.

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


0

Компоненты в архитектуре веб-приложений включают в себя:

1: Браузер: взаимодействие с клиентом

        HTML
        JavaScript
        Stylesheet

2: Интернет

3: веб-сервер

        CSS
        Image
        Pages(Java render )

4: Сервер приложений

        App Webapp (Java interaction)
        Others WebApps

5: Сервер базы данных

        Oracle, SQL, MySQL

6: Данные

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.