Descrivere l'architettura che si utilizza per le applicazioni Web Java? [chiuso]


146

Condividiamo architetture di applicazioni Web basate su Java!

Esistono molte architetture diverse per le applicazioni Web che devono essere implementate utilizzando Java. Le risposte a questa domanda possono fungere da libreria di vari progetti di applicazioni Web con i loro pro e contro. Mentre mi rendo conto che le risposte saranno soggettive, proviamo ad essere il più oggettivi possibile e motivare i pro ei contro che elenchiamo.

Usa il livello di dettaglio che preferisci per descrivere la tua architettura. Affinché la tua risposta abbia valore, dovrai almeno descrivere le principali tecnologie e idee utilizzate nell'architettura che descrivi. E, ultimo ma non meno importante, quando dovremmo usare la tua architettura?

Inizierò...


Panoramica dell'architettura

Utilizziamo un'architettura a 3 livelli basata su standard aperti di Sun come Java EE, Java Persistence API, Servlet e Java Server Pages.

  • Persistenza
  • Attività commerciale
  • Presentazione

I possibili flussi di comunicazione tra i livelli sono rappresentati da:

Persistence <-> Business <-> Presentation

Che, ad esempio, significa che il livello di presentazione non chiama o esegue mai operazioni di persistenza, lo fa sempre attraverso il livello aziendale. Questa architettura è destinata a soddisfare le esigenze di un'applicazione Web ad alta disponibilità.

Persistenza

Esegue operazioni di persistenza di creazione, lettura, aggiornamento ed eliminazione ( CRUD ). Nel nostro caso utilizziamo JPA ( Java Persistence API ) e attualmente utilizziamo Hibernate come nostro provider di persistenza e utilizziamo EntityManager .

Questo livello è diviso in più classi, in cui ogni classe si occupa di un certo tipo di entità (ovvero le entità correlate a un carrello della spesa potrebbero essere gestite da una singola classe di persistenza) ed è utilizzata da un solo gestore .

Inoltre questo strato memorizza anche entità JPA che sono cose come Account, ShoppingCartecc.

Attività commerciale

Tutta la logica collegata alla funzionalità dell'applicazione Web si trova in questo livello. Questa funzionalità potrebbe essere un trasferimento di denaro per un cliente che desidera pagare un prodotto online utilizzando la sua carta di credito. Potrebbe anche essere la creazione di un nuovo utente, l'eliminazione di un utente o il calcolo del risultato di una battaglia in un gioco basato sul Web.

Questo livello è diviso in più classi e ciascuna di queste classi viene annotata @Statelessper diventare un bean di sessione stateless (SLSB). Ogni SLSB è chiamato manager e per esempio un manager può essere una classe annotata come detto chiamato AccountManager.

Quando è AccountManagernecessario eseguire operazioni CRUD, effettua le chiamate appropriate a un'istanza di AccountManagerPersistence, che è una classe nel livello di persistenza. Uno schizzo approssimativo di due metodi AccountManagerpotrebbe essere:

...
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
}

Usiamo le transazioni del gestore di container in modo da non dover fare la demarcazione delle transazioni di noi stessi. Ciò che sostanzialmente accade sotto il cofano è che iniziamo una transazione quando si inserisce il metodo SLSB e lo commettiamo (o eseguiamo il rollback) immediatamente prima di uscire dal metodo. È un esempio di convenzione sulla configurazione, ma non abbiamo ancora avuto bisogno di altro che predefinito, Richiesto.

Ecco come il tutorial Java EE 5 di Sun spiega l' attributo Transaction richiesto per Enterprise JavaBeans (EJB):

Se il client è in esecuzione all'interno di una transazione e invoca il metodo del bean enterprise, il metodo viene eseguito all'interno della transazione del client. Se il client non è associato a una transazione, il contenitore avvia una nuova transazione prima di eseguire il metodo.

L'attributo Richiesto è l'attributo di transazione implicita per tutti i metodi bean enterprise in esecuzione con demarcazione delle transazioni gestite dal contenitore. In genere non si imposta l'attributo Richiesto a meno che non sia necessario sovrascrivere un altro attributo di transazione. Poiché gli attributi di transazione sono dichiarativi, è possibile modificarli facilmente in un secondo momento.

Presentazione

Il nostro livello di presentazione è responsabile di ... presentazione! È responsabile dell'interfaccia utente e mostra informazioni all'utente costruendo pagine HTML e ricevendo l'input dell'utente tramite richieste GET e POST. Attualmente stiamo utilizzando la vecchia combinazione Servlet di + Java Server Pages ( JSP ).

Il livello chiama i metodi nei gestori del livello aziendale per eseguire le operazioni richieste dall'utente e per ricevere informazioni da mostrare nella pagina Web. A volte le informazioni ricevute dal livello di business sono i tipi meno complesse come String's e intEgers, e in altri momenti entità JPA .

Pro e contro con l'architettura

Professionisti

  • Avere tutto ciò che riguarda un modo specifico di perseverare in questo livello significa solo che possiamo passare dall'uso dell'APP a qualcos'altro, senza dover riscrivere nulla nel livello aziendale.
  • È facile per noi scambiare il nostro livello di presentazione in qualcos'altro, ed è probabile che lo faremo se troviamo qualcosa di meglio.
  • Consentire al contenitore EJB di gestire i limiti delle transazioni è utile.
  • L'uso di + JPA di Servlet è facile (per cominciare) e le tecnologie sono ampiamente utilizzate e implementate in molti server.
  • L'uso di Java EE dovrebbe semplificarci la creazione di un sistema ad alta disponibilità con bilanciamento del carico e failover . Entrambi sentiamo di dover avere.

Contro

  • Utilizzando JPA è possibile archiviare query utilizzate spesso come query denominate utilizzando l' @NamedQueryannotazione sulla classe entità JPA. Se hai il più possibile correlato alla persistenza nelle classi di persistenza, come nella nostra architettura, questo spiegherà le posizioni in cui potresti trovare query per includere anche le entità JPA. Sarà più difficile dare una panoramica delle operazioni di persistenza e quindi più difficile da mantenere.
  • Abbiamo entità JPA come parte del nostro livello di persistenza. Ma Accounte ShoppingCart, non sono in realtà oggetti di business? È fatto in questo modo poiché devi toccare queste classi e trasformarle in entità che JPA sa come gestire.
  • Le entità JPA, che sono anche i nostri oggetti business, sono create come Data Transfer Objects ( DTO ), noto anche come Value Objects (VO). Ciò si traduce in un modello di dominio anemico poiché gli oggetti business non hanno una logica propria tranne i metodi di accesso. Tutta la logica viene eseguita dai nostri manager nel livello aziendale, che si traduce in uno stile di programmazione più procedurale. Non è un buon design orientato agli oggetti, ma forse non è un problema? (Dopo tutto l'orientamento agli oggetti non è l'unico paradigma di programmazione che ha prodotto risultati.)
  • L'uso di EJB e Java EE introduce un po 'di complessità. E non possiamo usare puramente Tomcat (l'aggiunta di un micro-contenitore EJB non è puramente Tomcat).
  • Ci sono molti problemi con l'utilizzo di Servlet + JPA. Utilizza Google per ulteriori informazioni su questi problemi.
  • Poiché le transazioni vengono chiuse all'uscita dal livello aziendale, non è possibile caricare alcuna informazione dalle entità JPA che è configurata per essere caricata dal database quando è necessario (utilizzando fetch=FetchType.LAZY) dall'interno del livello presentazione. Attiverà un'eccezione. Prima di restituire un'entità che contiene questo tipo di campi, dobbiamo essere sicuri di chiamare i getter pertinenti. Un'altra opzione è utilizzare Java Persistence Query Language ( JPQL ) e fare un FETCH JOIN. Tuttavia entrambe queste opzioni sono un po 'ingombranti.

1
Sembra che tu abbia impostato il livello troppo alto con la tua risposta - potrebbe aver scoraggiato gli altri :)
Jonik

5
Inoltre, forse la tua opinione dovrebbe essere una risposta normale, non parte della domanda, in modo che possa essere votata insieme ad altre risposte?
Jonik,

Questa domanda è stata referenziata su meta.
D4V1D,

Risposte:


20

Ok, ne farò uno (più corto):

  • Frontend: Tapestry (3 per i progetti più vecchi, 5 per i progetti più recenti)
  • Livello aziendale: primavera
  • DAO: Ibatis
  • Database: Oracle

Usiamo il supporto delle transazioni Sping e iniziamo le transazioni entrando nel livello di servizio, propagandoci fino alle chiamate DAO. Il livello di servizio ha la maggior conoscenza del modello di business e i DAO svolgono un lavoro CRUD relativamente semplice.

Alcune query più complicate sono gestite da query più complicate nel backend per motivi di prestazioni.

Il vantaggio di usare Spring nel nostro caso è che possiamo avere istanze dipendenti dal paese / dalla lingua, che sono alla base di una classe Proxy Spring. In base all'utente nella sessione, durante l'esecuzione di una chiamata viene utilizzata l'implementazione corretta di paese / lingua.

La gestione delle transazioni è quasi trasparente, rollback sulle eccezioni di runtime. Utilizziamo eccezioni non controllate il più possibile. Facevamo eccezioni verificate, ma con l'introduzione di Spring vedo i vantaggi di eccezioni non controllate, gestendo le eccezioni solo quando è possibile. Evita un sacco di roba "cattura / ripeti" o "lancia".

Mi dispiace è più breve del tuo post, spero che tu lo trovi interessante ...


Bella risposta! Questa discussione sembra attrarre un po 'di traffico, peccato che altre persone non sentano di avere il tempo di descrivere le proprie architetture o di avere altri motivi per non partecipare.

19

Tecnologie di sviluppo Web ideali basate su Java oggi.

Livello Web:

HTML + CSS + Ajax + JQuery

RESTFul Web Controller / Azione / Livello elaborazione richieste:

Gioca a Framework

Logica aziendale / Livello di servizio:

Utilizzare il codice Java puro il più a lungo possibile. Si può fare fusione di servizi web qui.

Livello di trasformazione dati XML / JSon:

XMLTool (Cerca su Google Code), JSoup, Google GSon, XStream, JOOX (Cerca su Google Code)

Strato di persistenza:

CRUD: JPA o SienaProject o QueryDSL / Query complesse: JOOQ, QueryDSL


9

Ecco i miei 5 centesimi

Presentazione

Android, Angular.JS WebClient, OAUTHv2

API

REST, Jersey (JAX-RS), Jackson (de / serializzazione JSON), oggetti DTO (diversi dai modelli di logica aziendale)

Logica di business

Molla per la gestione di DI ed eventi. Approccio DDD-ish di oggetti modello. I lavori in esecuzione più lunghi vengono scaricati con SQS nei moduli di lavoro.

DAO

Modello di repository con modelli JDBC Spring per memorizzare entità. Redis (JEDIS) per classifiche, usando gli elenchi ordinati. Memcache per Token Store.

Banca dati

MySQL, Memcached, Redis


Questo è qualcosa di simile a ciò che seguiamo anche nei nostri progetti! Inoltre JBPM per il flusso di lavoro aziendale. Perché nessuna primavera mi chiedo?
ininprsr,

Dovrei fare un aggiornamento con il nostro arco attuale: attualmente utilizziamo i template Spring DI e JDBC per il livello di accesso ai dati.
Pepster,

6

Ciò che abbiamo seguito nel nostro progetto è:

Tecnologia front-end

  • AngularJS
  • HTML5
  • css3
  • Javascript
  • Bootstrap 3

API

  1. RIPOSO
  2. MAGLIA (JAX-RS)
  3. STIA TRANQUILLO
  4. STIVALE A MOLLA
  5. Jackson
  6. sicurezza primaverile

Logica di business

  • DATI DI PRIMAVERA

  • Dati PRIMAVERA MongoDB

Banca dati

  • MongoDB

Server (per la memorizzazione nella cache)

  • Redis

4

Stiamo ancora usando il solito stack Struts-Spring-Hibernate.

Per le app future, stiamo esaminando Spring Web Flow + Spring MVC + Hibernate o Spring + Hibernate + Web Services con front-end Flex.

Una caratteristica distintiva della nostra architettura è la modularizzazione. Abbiamo un numero di moduli, alcuni a partire da 3 a un massimo di 30 tabelle nel database. La maggior parte dei moduli è costituita da progetti aziendali e Web. Il progetto di business mantiene la logica di business e di persistenza, mentre il web mantiene la logica di presentazione.
A livello logico, ci sono tre livelli: Affari, Persistenza e Presentazione.
Dipendenze: la
presentazione dipende dal business e dalla persistenza.
La persistenza dipende dagli affari.
Il business non dipende da altri livelli.

La maggior parte dei progetti aziendali ha tre tipi di interfacce (nota: non GUI, è un livello di interfaccia java programmatico).

  1. Interfaccia che la presentazione utilizza come client
  2. Interfaccia utilizzata da altri moduli quando sono client del modulo.
  3. Interfaccia che può essere utilizzata per scopi amministrativi del modulo.

Spesso 1 estende 2. In questo modo è facile sostituire un'implementazione del modulo con un'altra. Questo ci aiuta ad adottare clienti diversi e ad integrarci più facilmente. Alcuni clienti compreranno solo determinati moduli e abbiamo bisogno di integrare funzionalità che già hanno. Poiché l'interfaccia e il livello di implementazione sono separati, è facile implementare l'implementazione del modulo ad-hock per quel client specifico senza influire sui moduli dipendenti. E Spring Framework semplifica l'iniezione di diverse implementazioni.

Il nostro livello aziendale si basa su POJO. Una tendenza che sto osservando è che questi POJO assomigliano a DTO. Soffriamo di modello di dominio anemico . Non sono del tutto sicuro del perché questo accada, ma può essere dovuto alla semplicità del dominio problematico di molti dei nostri moduli, la maggior parte del lavoro è CRUD o perché gli sviluppatori preferiscono posizionare la logica altrove.


3

Ecco un'altra architettura web su cui ho lavorato:

Uno dei requisiti principali era che l'applicazione dovrebbe supportare cellulari / altri dispositivi. L'applicazione dovrebbe inoltre essere estensibile o flessibile ai cambiamenti nelle scelte tecnologiche.

Livello di presentazione:

  • JSP / JQuery (MVC lato client)
  • Android nativo
  • IPhone nativo
  • Web mobile (HTML5 / CSS3 / Responsive design)

  • Controller Spring REST (può passare a JAX-RS)

Livello di servizio aziendale:

Spring @Service (può cambiare in bean stateless)

Livello di accesso ai dati:

Spring @Repository (può cambiare in bean stateless)

Livello di risorsa:

Entità di ibernazione (JPA) (può passare a qualsiasi ORM)

Puoi trovare maggiori informazioni sul libro che segue questa architettura qui .


2

IMHO, molti di noi hanno un denominatore comune. Almeno nel back-end, abbiamo una qualche forma di contenitore IOC / DI e un framework di persistenza. Personalmente uso Guice e Mybatis per questo. Le differenze sono nel modo in cui implementiamo il livello view / UI / presentation. Ci sono 2 opzioni principali qui (potrebbero essere più). Basato sull'azione (URL mappati ai controller) e basato sui componenti. Attualmente sto usando un livello di presentazione basato su componenti (usando wicket). Imita perfettamente un ambiente desktop in cui utilizzo componenti ed eventi anziché URL e controller. Attualmente sto cercando un motivo per cui dovrei migrare a questo tipo di architettura di controller URL (è così che sono finito in questa pagina). Perché l'hype su architetture RESTful e Stateless.

Per rispondere a questa domanda in breve: scrivo applicazioni web stateful usando un framework orientato ai componenti sopra il contenitore IOC di Guice e inserisco i dati nel database relazionale usando Mybatis.


1

Un po 'diverso, e direi qui un'architettura java più modulare. Abbiamo:

  1. Frontale Spring WS / Rest / JSP
  2. Spring MVC per la logica dei servizi aziendali, contenente la logica del livello di presentazione e le transazioni Spring
  3. Interfaccia di comunicazione del servizio componenti, cercata attraverso EJB dai servizi alle imprese. Gli EJB definiscono i propri limiti di transazione in grado di unire le transazioni Spring.
  4. Implementazioni del servizio componenti, di nuovo componenti Spring
  5. Livello di integrazione, MyBatis per integrazioni di database, Spring WS per integrazioni di servizi Web, altre tecnologie di integrazione per altri servizi
  6. Mainframe, database, altri servizi su altri server ...

Oltre a quanto sopra, abbiamo i moduli di libreria condivisa che è un provider di funzionalità comune per tutti i dispositivi.

L'uso di diversi strati ci consente il disaccoppiamento completo e la modularità di cui abbiamo bisogno. Siamo inoltre in grado di sfruttare appieno la potenza di Java EE e di Spring. Nulla ci impedisce di utilizzare JSF, ad esempio, per il front-end, se necessario.

Rispetto all'esempio di architettura di OP, penso che questo possa essere descritto come con quattro livelli principali anziché tre, sebbene con una svolta.


0

Ho lavorato su progetti che usano quel rigido schema manageriale. Storicamente, ero un grande sostenitore della rigida gerarchia in cui tutto rientrava in una scatola ordinata. Mentre progredisco nella mia carriera, trovo che sia costretto in molti casi. Credo che l'adozione di una mentalità più agile verso la progettazione dell'applicazione porti a un prodotto migliore. Cosa intendo con questo creando un insieme di classi che risolvono il problema a portata di mano. Piuttosto che dire "Hai creato un manager per questo e quello?"

Il progetto attuale a cui sto lavorando è un'app Web con una combinazione di chiamate Spring MVC e RestEasy JSON / Ajax. Sul lato server incorporato nei nostri controller è presente un livello dati basato sulla facciata sensibile con JPA / ibernazione per l'accesso diretto al database, alcuni accessi EJB e alcune chiamate ai servizi Web basate su SOAP. Unendo tutto questo è un codice del controller java personalizzato che determina cosa serializzare come JSON e restituire al client.

Non passiamo quasi il tempo a tentare di creare un modello unificato, invece di optare per l'adozione dell'idea "Peggio è meglio" della filosofia del design Unix. Essendo che è molto meglio colorare al di fuori delle linee e costruire qualcosa di sensato, in fretta piuttosto che costruire qualcosa che aderisce a un mucchio di rigidi mandati di progettazione.


0

I componenti di Web Application Architecture includono:

1: Browser: interazione client

        HTML
        JavaScript
        Stylesheet

2: Internet

3: Webserver

        CSS
        Image
        Pages(Java render )

4: Server applicazioni

        App Webapp (Java interaction)
        Others WebApps

5: Database Server

        Oracle, SQL, MySQL

6: Dati

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.