Java 기반 웹 애플리케이션 아키텍처를 공유하십시오!
Java를 사용하여 구현해야하는 웹 응용 프로그램을위한 다양한 아키텍처가 있습니다. 이 질문에 대한 답변은 장단점이있는 다양한 웹 응용 프로그램 디자인의 라이브러리 역할을 할 수 있습니다. 나는 그 대답이 주관적이라는 것을 알고 있지만, 가능한 한 객관적이되고 우리가 제시 한 장단점에 동기를 부여하도록합시다.
아키텍처를 설명하기 위해 원하는 세부 수준을 사용하십시오. 당신의 대답이 어떤 가치를 갖기 위해서는 최소한 당신이 묘사 한 아키텍처에 사용 된 주요 기술과 아이디어를 설명해야합니다. 마지막으로 아키텍처를 언제 사용해야합니까?
시작하겠습니다 …
아키텍처 개요
Java EE, Java Persistence API, Servlet 및 Java Server Pages와 같은 Sun의 개방형 표준을 기반으로하는 3 계층 아키텍처를 사용합니다.
- 고집
- 사업
- 표시
계층 간 가능한 통신 흐름은 다음과 같이 표시됩니다.
Persistence <-> Business <-> Presentation
예를 들어, 프리젠 테이션 계층은 지속성 작업을 호출하거나 지속하지 않으며 항상 비즈니스 계층을 통해 수행합니다. 이 아키텍처는 고 가용성 웹 응용 프로그램의 요구를 충족시키기위한 것입니다.
고집
CRUD ( Create , Read, Update and Delete ) 지속성 작업을 수행합니다. 우리의 경우에는 ( Java Persistence API ) JPA를 사용하고 있으며 현재는 Hibernate 를 지속성 공급자로 사용 하고 EntityManager를 사용 합니다 .
이 계층은 여러 클래스로 구분되며, 각 클래스는 특정 유형의 엔티티 (예 : 장바구니 관련 엔티티가 단일 지속성 클래스에 의해 처리 될 수 있음)를 처리하며 하나의 관리자 만 사용 합니다 .
또한,이 층은 또한 저장 JPA 엔티티 것들처럼되어 Account
, ShoppingCart
등등
사업
웹 응용 프로그램 기능과 관련된 모든 논리는이 계층에 있습니다. 이 기능은 신용 카드를 사용하여 온라인으로 제품에 대한 비용을 지불하려는 고객에게 송금을 시작할 수 있습니다. 웹 기반 게임에서 새로운 사용자를 생성하거나 사용자를 삭제하거나 전투 결과를 계산할 수도 있습니다.
이 계층은 여러 클래스로 나뉘며 각 클래스에는 SLSB ( Stateless Session Bean)@Stateless
가되도록 주석이 달려 있습니다. 각 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 메서드를 시작할 때 트랜잭션을 시작하고 메서드를 종료하기 직전에 커밋 (또는 롤백)하는 것입니다. 구성에 대한 관례의 예이지만 기본, 필수 이외의 다른 것은 필요하지 않았습니다.
다음은 Sun의 Java EE 5 Tutorial이 EJB (Enterprise JavaBeans) 의 필수 트랜잭션 속성 을 설명하는 방법입니다 .
클라이언트가 트랜잭션 내에서 실행 중이고 엔터프라이즈 Bean의 메소드를 호출하면 메소드는 클라이언트의 트랜잭션 내에서 실행됩니다. 클라이언트가 트랜잭션과 연결되어 있지 않으면 컨테이너는 메소드를 실행하기 전에 새 트랜잭션을 시작합니다.
필수 속성은 컨테이너 관리 트랜잭션 경계 설정으로 실행되는 모든 엔터프라이즈 Bean 메소드에 대한 내재적 트랜잭션 속성입니다. 다른 트랜잭션 속성을 대체하지 않으면 일반적으로 필수 속성을 설정하지 않습니다. 트랜잭션 속성은 선언적이므로 나중에 쉽게 변경할 수 있습니다.
표시
프레젠테이션 레이어는 … 프레젠테이션을 담당합니다! 사용자 인터페이스를 담당하며 HTML 페이지를 작성하고 GET 및 POST 요청을 통해 사용자 입력을 수신하여 사용자에게 정보를 표시합니다. 우리는 현재 구 서블릿 + JSP (Java Server Pages ) 조합을 사용하고 있습니다.
계층 은 비즈니스 계층 관리자 에서 메소드를 호출 하여 사용자가 요청한 작업을 수행하고 웹 페이지에 표시 할 정보를 수신합니다. 때로는 비즈니스 계층으로부터 수신 된 정보는 덜 복잡한 종류 String
의와 int
egers, 그리고 다른 배에서 JPA 엔티티 .
아키텍처의 장단점
찬성
- 이 계층에서 지속성을 유지하는 특정 방법과 관련된 모든 것이 있다는 것은 비즈니스 계층에서 아무것도 다시 작성할 필요없이 JPA 사용에서 다른 것으로 바꿀 수 있다는 의미 일뿐입니다.
- 프리젠 테이션 레이어를 다른 것으로 쉽게 교체 할 수 있으며 더 나은 것을 찾게 될 것입니다.
- EJB 컨테이너가 트랜잭션 경계를 관리하게하는 것이 좋습니다.
- 서블릿의 + JPA를 사용하는 것은 쉬우 며 (처음부터) 기술은 많은 서버에서 널리 사용되고 구현됩니다.
- Java EE를 사용하면 로드 밸런싱 및 페일 오버 기능을 갖춘 고 가용성 시스템을보다 쉽게 만들 수 있습니다 . 둘 다 우리는 반드시 있어야한다고 느낍니다.
단점
- JPA를 사용
@NamedQuery
하면 JPA 엔터티 클래스 의 주석을 사용하여 자주 사용하는 쿼리를 명명 된 쿼리로 저장할 수 있습니다 . 아키텍처에서와 같이 지속성 클래스의 지속성과 관련이있는 경우 JPA 엔티티를 포함하는 쿼리를 찾을 수있는 위치가 분산됩니다. 지속성 작업을 개괄하기가 더 어려워 유지 관리가 더 어려워집니다. - 지속성 계층의 일부로 JPA 엔티티가 있습니다. 그러나
Account
하고ShoppingCart
, 그들은 정말 비즈니스 오브젝트 않나요? 이러한 클래스를 터치하고 JPA가 처리하는 방법을 알고있는 엔티티로 전환해야하므로이 방식으로 수행됩니다. - 비즈니스 오브젝트이기도 한 JPA 엔티티는 VO (Value Objects)라고도하는 DTO (Data Transfer Object)와 같이 작성 됩니다. 에서이 결과 빈혈 도메인 모델 비즈니스 객체로는 접근 방법을 제외하고 자신의 어떤 로직이 없습니다. 모든 로직은 비즈니스 계층의 관리자가 수행하므로보다 절차적인 프로그래밍 스타일이됩니다. 좋은 객체 지향 디자인은 아니지만 문제가되지 않을 수도 있습니다. (모든 객체 지향 이후 결과를 제공 한 유일한 프로그래밍 패러다임은 아닙니다.)
- EJB와 Java EE를 사용하면 약간의 복잡성이 발생합니다. 그리고 우리는 순수 Tomcat을 사용할 수 없습니다 (EJB 마이크로 컨테이너를 추가하는 것이 순전히 Tomcat 이 아닙니다 ).
- 서블릿 + JPA 사용과 관련된 많은 문제가 있습니다. 이러한 문제에 대한 자세한 내용을 보려면 Google을 사용하십시오.
- 비즈니스 계층을 종료 할 때 트랜잭션이 닫히
fetch=FetchType.LAZY
므로 프리젠 테이션 계층 내부에서 필요할 때 (사용 ) 데이터베이스에서로드되도록 구성된 JPA 엔티티의 정보를로드 할 수 없습니다 . 예외가 발생합니다. 이러한 종류의 필드가 포함 된 엔터티를 반환하기 전에 관련 getter를 호출해야합니다. 또 다른 옵션은 JPQL (Java Persistence Query Language)을 사용 하고을 수행하는 것FETCH JOIN
입니다. 그러나이 두 옵션은 약간 번거 롭습니다.
답변
좋아, 나는 (짧은) 것을 할 것이다.
- 프론트 엔드 : 태피스트리 (이전 프로젝트의 경우 3 개, 최신 프로젝트의 경우 5 개)
- 비즈니스 계층 : 봄
- DAO : 이바 티스
- 데이터베이스 : 오라클
Sping 트랜잭션 지원을 사용하고 서비스 계층에 진입하면 DAO 호출로 전파되는 트랜잭션을 시작합니다. 서비스 계층은 탈취 모델 지식이 가장 많으며 DAO는 비교적 간단한 CRUD 작업을 수행합니다.
좀 더 복잡한 쿼리 항목은 성능상의 이유로 백엔드에서 더 복잡한 쿼리에 의해 처리됩니다.
우리의 경우 Spring을 사용하는 이점은 Spring Proxy 클래스 뒤에있는 국가 / 언어 의존 인스턴스를 가질 수 있다는 것입니다. 세션의 사용자를 기반으로 전화를 걸 때 올바른 국가 / 언어 구현이 사용됩니다.
트랜잭션 관리는 거의 투명하고 런타임 예외에 대한 롤백입니다. 검사되지 않은 예외는 가능한 많이 사용합니다. 우리는 예 외를 확인했지만 Spring이 도입되면서 확인되지 않은 예외의 이점을 볼 수 있으며 가능한 경우에만 예외를 처리합니다. 많은 상용구 “캐치 / 재 스로”또는 “던지기”를 피합니다.
죄송합니다. 게시물보다 짧습니다.이 흥미로운 내용을 찾으시기 바랍니다.
답변
오늘날 이상적인 Java 기반 웹 개발 기술.
웹 레이어 :
HTML + CSS + Ajax + JQuery
RESTFul 웹 컨트롤러 / 액션 / 요청 처리 계층 :
플레이 프레임 워크
비즈니스 로직 / 서비스 계층 :
가능한 오래 순수 Java 코드를 사용하십시오. 여기서 웹 서비스의 융합을 할 수 있습니다.
XML / JSon 데이터 변환 계층 :
XMLTool (Google 코드 검색), JSoup, Google GSon, XStream, JOOX (Google 코드 검색)
지속성 레이어 :
CRUD : JPA 또는 SienaProject 또는 QueryDSL / 복합 쿼리 : JOOQ, QueryDSL
답변
여기 내 5 센트
표시
안드로이드, Angular. JS WebClient, OAUTHv2
API
REST, Jersey (JAX-RS), Jackson (JSON de / serialisation), DTO 객체 (비즈니스 로직 모델과 다름)
비즈니스 로직
DI 및 이벤트 처리를위한 스프링. 모델 객체의 DDD-ish 접근. 더 긴 실행 작업은 작업자 모듈에서 SQS와 함께 오프로드됩니다.
DAO
엔티티를 저장하기 위해 Spring JDBC 템플릿을 사용하는 저장소 모델. 순서 목록을 사용하는 리더 보드 용 Redis (JEDIS). 토큰 스토어 용 Memcache.
데이터 베이스
MySQL, Memcached, 레디 스
답변
우리 프로젝트에서 따라온 것은 :
프런트 엔드 기술
- AngularJS
- HTML5
- CSS3
- 자바 스크립트
- 부트 스트랩 3
API
- 쉬다
- 저지 (JAX-RS)
- 휴식을 취하다
- 봄 부트
- 잭슨
- 봄 보안
비즈니스 로직
-
스프링 데이터
-
SPRING 데이터 MongoDB
데이터베이스
- 몽고 DB
서버 (캐싱 용)
- 레디 스
답변
우리는 여전히 일반적인 Struts-Spring-Hibernate 스택을 사용하고 있습니다.
향후 앱을 위해 Flex 프론트 엔드를 사용하는 Spring Web Flow + Spring MVC + Hibernate 또는 Spring + Hibernate + Web Services를 살펴보고 있습니다.
아키텍처의 특징은 모듈화입니다. 데이터베이스에는 3 개에서 최대 30 개의 테이블로 시작하는 많은 모듈이 있습니다. 대부분의 모듈은 비즈니스 및 웹 프로젝트로 구성됩니다. 비즈니스 프로젝트는 비즈니스 및 지속성 논리를 보유하고 웹은 프리젠 테이션 논리를 보유합니다.
논리적 수준에는 비즈니스, 지속성 및 프리젠 테이션의 세 가지 계층이 있습니다.
종속성 :
프레젠테이션은 비즈니스 및 지속성에 따라 다릅니다.
지속성은 비즈니스에 달려 있습니다.
비즈니스는 다른 계층에 의존하지 않습니다.
대부분의 비즈니스 프로젝트에는 세 가지 유형의 인터페이스가 있습니다 (주 : GUI가 아니라 프로그래밍 가능한 Java 인터페이스 계층 임).
- 프리젠 테이션이 클라이언트로 사용중인 인터페이스
- 다른 모듈이 모듈의 클라이언트 일 때 사용하는 인터페이스.
- 모듈의 관리 목적으로 사용할 수있는 인터페이스.
종종 1은 2를 확장합니다. 이런 방식으로 한 모듈 구현을 다른 구현으로 쉽게 교체 할 수 있습니다. 이를 통해 우리는 다른 고객을 수용하고 더 쉽게 통합 할 수 있습니다. 일부 고객은 특정 모듈 만 구매하므로 이미 보유한 기능을 통합해야합니다. 인터페이스와 구현 계층이 분리되어 있기 때문에 종속 모듈에 영향을주지 않고 특정 클라이언트에 대한 애드혹 모듈 구현을 쉽게 구현할 수 있습니다. 스프링 프레임 워크를 사용하면 다양한 구현을 쉽게 주입 할 수 있습니다.
비즈니스 계층은 POJO를 기반으로합니다. 내가 관찰하고있는 한 가지 경향은 이러한 POJO가 DTO와 유사하다는 것입니다. 빈혈 도메인 모델로 고통 받고 있습니다 . 왜 이런 일이 일어나는지 잘 모르겠지만 많은 모듈의 문제 영역이 단순하기 때문일 수 있습니다. 대부분의 작업은 CRUD이거나 개발자가 다른 곳에 논리를 배치하는 것을 선호합니다.
답변
내가 한 웹 아키텍처가 하나 더 있습니다.
주요 요구 사항 중 하나는 응용 프로그램이 모바일 / 다른 장치를 지원해야한다는 것입니다. 응용 프로그램은 기술 선택의 변경에 따라 확장 가능하거나 유연해야합니다.
프레젠테이션 계층 :
- JSP / JQuery (클라이언트 측 MVC)
- 네이티브 안드로이드
- 네이티브 아이폰
-
모바일 웹 (HTML5 / CSS3 / 응답 디자인)
-
스프링 REST 컨트롤러 (JAX-RS로 변경 가능)
비즈니스 서비스 계층 :
Spring @Service (Stateless EJB로 변경 가능)
데이터 액세스 계층 :
Spring @Repository (상태 비 저장 EJB로 변경 가능)
리소스 계층 :
최대 절전 모드 (JPA) 엔티티 (ORM으로 변경할 수 있음)
이 아키텍처를 따르는 책에 대한 자세한 내용은 여기를 참조하십시오 .
답변
IMHO, 우리 대부분은 공통 분모를 가지고 있습니다. 백엔드에서 우리는 일종의 IOC / DI 컨테이너와 지속성 프레임 워크를 가지고 있습니다. 개인적으로 Guice와 Mybatis를 사용합니다. 차이점은 view / UI / presentation 레이어를 구현하는 방법에 있습니다. 여기에는 2 가지 주요 옵션이 있습니다 (더 많을 수도 있음) .. 작업 기반 (컨트롤러에 매핑 된 URL) 및 구성 요소 기반. 현재 컴포넌트 기반 프리젠 테이션 레이어를 사용하고 있습니다 (위켓 사용). URL 및 컨트롤러 대신 구성 요소 및 이벤트를 사용하는 데스크톱 환경을 완벽하게 모방합니다. 현재이 URL 컨트롤러 아키텍처로 마이그레이션 해야하는 이유를 찾고 있습니다 (이 페이지에서 끝났습니다). RESTful 및 Stateless 아키텍처에 대한 과대 광고가 필요한 이유
이 질문에 간단히 대답하기 위해 : Guice IOC 컨테이너 위에 구성 요소 지향 프레임 워크를 사용하여 상태 저장 웹 응용 프로그램을 작성하고 Mybatis를 사용하여 관계형 데이터베이스에 데이터를 넣습니다.