Java web uygulamaları için kullandığınız mimariyi açıklayın. [kapalı]


147

Java tabanlı web uygulama mimarilerini paylaşalım!

Java kullanılarak uygulanacak web uygulamaları için çok sayıda farklı mimari vardır. Bu sorunun cevapları, artıları ve eksileri ile çeşitli web uygulama tasarımlarının bir kütüphanesi olarak hizmet edebilir. Cevapların öznel olacağını anlarken, olabildiğince objektif olmaya ve listelediğimiz artıları ve eksileri motive etmeye çalışalım.

Mimarinizi tanımlamak için tercih ettiğiniz ayrıntı düzeyini kullanın. Cevabınızın herhangi bir değere sahip olması için, en azından tanımladığınız mimaride kullanılan başlıca teknolojileri ve fikirleri tanımlamanız gerekecek. Ve son olarak , mimarinizi ne zaman kullanmalıyız?

Başlayacağım ...


Mimariye genel bakış

Java EE, Java Persistence API, Servlet ve Java Server Pages gibi Sun'ın açık standartlarına dayalı 3 katmanlı bir mimari kullanıyoruz.

  • Kalıcılık
  • İş
  • Sunum

Katmanlar arasındaki olası iletişim akışları şu şekilde temsil edilir:

Persistence <-> Business <-> Presentation

Bu, örneğin sunum katmanının hiçbir zaman kalıcılık işlemlerini çağırmadığı veya gerçekleştirmediği anlamına gelir, bunu her zaman iş katmanı aracılığıyla yapar. Bu mimari, yüksek kullanılabilirliğe sahip bir web uygulamasının taleplerini karşılamaya yöneliktir.

Kalıcılık

Oluşturma, okuma, güncelleme ve silme ( CRUD ) kalıcılık işlemlerini gerçekleştirir. Bizim durumumuzda ( Java Persistence API ) JPA kullanıyoruz ve şu anda kalıcılık sağlayıcımız olarak Hibernate kullanıyoruz ve EntityManager'ı kullanıyoruz .

Bu katman, her bir sınıfın belirli türden varlıklarla uğraştığı (yani bir alışveriş sepetiyle ilgili varlıklar tek bir kalıcılık sınıfı tarafından ele alınabilir) ve bir ve yalnızca bir yönetici tarafından kullanıldığı birden çok sınıfa bölünmüştür .

Ek olarak, bu katman aynı zamanda , vb. Şeyler olan JPA varlıklarını da depolar .AccountShoppingCart

İş

Web uygulaması işlevselliğine bağlı tüm mantık bu katmanda yer alır. Bu işlevsellik, bir ürün için kredi kartını kullanarak çevrimiçi ödeme yapmak isteyen bir müşteri için bir para transferi başlatıyor olabilir. Web tabanlı bir oyunda yeni bir kullanıcı oluşturmak, bir kullanıcıyı silmek veya bir savaşın sonucunu hesaplamak da olabilir.

Bu katman, birden çok sınıfa bölünmüştür ve bu sınıfların her biri, Stateless Session Bean (SLSB) @Statelesshaline gelmek için notlandırılmıştır. Her SLSB'ye yönetici adı verilir ve örneğin bir yönetici , adı verildiği gibi açıklamalı bir sınıf olabilir .AccountManager

Tüm AccountManagerihtiyaç CRUD işlemleri gerçekleştirmek için bu örneğine uygun çağrılar AccountManagerPersistencekalıcılık katmanındaki bir sınıftır. İki yöntemin kaba bir taslağı şunlar AccountManagerolabilir:

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

Biz kullanmak konteyner yöneticisi işlemlerini biz işlem çizilmesine bizim kendi 's yapmak zorunda kalmamak. Temelde başlık altında olan şey, SLSB yöntemine girerken bir işlem başlatmamız ve yöntemden çıkmadan hemen önce bunu taahhüt etmemiz (veya geri almamız). Bu, yapılandırma yerine bir kural örneği, ancak henüz varsayılan, Gerekli olan dışında hiçbir şeye ihtiyacımız olmadı.

Sun'dan Java EE 5 Eğitimi, Kurumsal JavaBeans (EJB'ler) için Gerekli işlem özelliğini şu şekilde açıklamaktadır :

Müşteri bir işlem içinde çalışıyorsa ve kurumsal Bean yöntemini çağırırsa, yöntem müşterinin işlemi içinde yürütülür. İstemci bir işlemle ilişkili değilse, kapsayıcı yöntemi çalıştırmadan önce yeni bir işlem başlatır.

Gerekli özniteliği, kapsayıcı tarafından yönetilen işlem sınırlamasıyla çalışan tüm kurumsal fasulye yöntemleri için örtük işlem özniteliğidir. Başka bir işlem özniteliğini geçersiz kılmanız gerekmedikçe, genellikle Gerekli özniteliği ayarlamazsınız. İşlem öznitelikleri bildirimsel olduğundan, bunları daha sonra kolayca değiştirebilirsiniz.

Sunum

Sunum katmanımız ... sunumdan sorumludur! Kullanıcı arayüzünden sorumludur ve HTML sayfaları oluşturarak ve GET ve POST istekleri aracılığıyla kullanıcı girdisi alarak kullanıcıya bilgileri gösterir. Şu anda eski Servlet'in + Java Sunucu Sayfaları ( JSP ) kombinasyonunu kullanıyoruz.

Katman , kullanıcı tarafından talep edilen işlemleri gerçekleştirmek ve web sayfasında gösterilecek bilgileri almak için iş katmanının yöneticilerindeki yöntemleri çağırır . Bazen iş katmanından alınan bilgiler gibi daha az karmaşık türleridir String'ler ve integers ve diğer zamanlarda en JPA varlıklar .

Mimarinin artıları ve eksileri

Artıları

  • Bu katmanda kalıcılık yapmanın belirli bir yolu ile ilgili her şeye sahip olmak, yalnızca, iş katmanında herhangi bir şeyi yeniden yazmak zorunda kalmadan JPA kullanmaktan başka bir şeye geçebileceğimiz anlamına gelir.
  • Sunum katmanımızı başka bir şeyle değiştirmek bizim için kolaydır ve daha iyi bir şey bulursak büyük olasılıkla bulacağız.
  • EJB konteynerinin işlem sınırlarını yönetmesine izin vermek güzel.
  • Servlet'in + JPA'sını kullanmak kolaydır (başlangıçta) ve teknolojiler yaygın olarak kullanılır ve birçok sunucuda uygulanır.
  • Java EE kullanımının, yük dengeleme ve yük devretme ile yüksek kullanılabilirlikli bir sistem oluşturmamızı kolaylaştırması gerekiyor . Her ikisine de sahip olmamız gerektiğini düşünüyoruz.

Eksileri

  • JPA kullanarak @NamedQuery, JPA varlık sınıfındaki açıklamayı kullanarak, sık kullanılan sorguları adlandırılmış sorgular olarak depolayabilirsiniz . Kalıcılık sınıflarında kalıcılıkla ilgili olabildiğince çok şeyiniz varsa, mimarimizdeki gibi, bu, JPA varlıklarını da içerecek sorguları bulabileceğiniz konumlara yayılacaktır. Kalıcılık operasyonlarını gözden geçirmek ve dolayısıyla sürdürmek daha zor olacaktır.
  • Kalıcılık katmanımızın bir parçası olarak JPA varlıklarımız var. Ama Accountve ShoppingCartonlar gerçekten iş nesneler değildir? Bu sınıflara dokunmanız ve onları JPA'nın nasıl idare edeceğini bildiği varlıklara dönüştürmeniz gerektiği için bu şekilde yapılır.
  • Aynı zamanda iş nesnelerimiz olan JPA varlıkları, Değer Nesneleri (VO'lar) olarak da bilinen Veri Aktarım Nesneleri ( DTO'lar ) gibi oluşturulur . Bu , iş nesnelerinin erişimci yöntemleri dışında kendi mantığına sahip olmadığı için anemik bir etki alanı modeliyle sonuçlanır . Tüm mantık, iş katmanındaki yöneticilerimiz tarafından yapılır ve bu da daha prosedürel bir programlama stiliyle sonuçlanır. İyi bir nesne yönelimli tasarım değil, ama belki bu bir sorun değil? (Sonuçta, sonuç veren tek programlama paradigması nesne yönelimi değildir.)
  • EJB ve Java EE'yi kullanmak biraz karmaşıklık getirir. Ve tamamen Tomcat kullanamayız (bir EJB mikro-kapsayıcı eklemek tamamen Tomcat değildir ).
  • Servlet'in + JPA kullanımıyla ilgili pek çok sorun var. Bu sorunlar hakkında daha fazla bilgi için Google'ı kullanın.
  • İş katmanından çıkılırken işlemler kapatıldığı için, ihtiyaç duyulduğunda (kullanılarak fetch=FetchType.LAZY) sunum katmanının içinden veritabanından yüklenmek üzere yapılandırılmış JPA varlıklarından herhangi bir bilgi yükleyemiyoruz . Bir istisnayı tetikleyecektir. Bu tür alanları içeren bir varlığı iade etmeden önce, ilgili alıcıları çağırdığımızdan emin olmalıyız. Diğer bir seçenek de Java Persistence Query Language ( JPQL ) kullanmak ve bir FETCH JOIN. Ancak bu seçeneklerin her ikisi de biraz külfetli.

1
Görünüşe göre çıtayı kendi cevabınızla çok yükseğe ayarlamışsınız - başkalarının cesaretini kırmış olabilir :)
Jonik

5
Ayrıca, belki de alacağınız normal bir cevap olmalı, sorunun bir parçası değil, böylece diğer cevaplarla birlikte oylanabilsin?
Jonik

Bu soruya meta üzerinde referans verilmiştir.
D4V1D

Yanıtlar:


20

Tamam (daha kısa) bir tane yapacağım:

  • Ön uç: Goblen (eski projeler için 3, yeni projeler için 5)
  • İş katmanı: Bahar
  • DAO'lar: Ibatis
  • Veritabanı: Oracle

Sping işlem desteğini kullanıyoruz ve hizmet katmanına girdikten sonra işlemleri başlatarak DAO çağrılarına yayılıyoruz. Hizmet katmanı en fazla iş modeli bilgisine sahiptir ve DAO'lar nispeten basit CRUD çalışması yapar.

Bazı daha karmaşık sorgu işleri, performans nedenleriyle arka uçta daha karmaşık sorgular tarafından ele alınır.

Bizim durumumuzda Spring kullanmanın avantajları, Spring Proxy sınıfının arkasında olan ülkeye / dile bağlı örneklere sahip olabilmemizdir. Oturumdaki kullanıcıya bağlı olarak, bir arama yapılırken doğru ülke / dil uygulaması kullanılır.

İşlem yönetimi neredeyse şeffaftır, çalışma zamanı istisnalarında geri alma. Mümkün olduğunca kontrol edilmeyen istisnaları kullanırız. Önceden kontrol edilmiş istisnalar yapardık, ancak Bahar'ın tanıtılmasıyla, istisnaları yalnızca elinizden geldiğince ele alarak, kontrol edilmemiş istisnaların faydalarını görüyorum. Pek çok standart "yakala / yeniden at" veya "fırlat" şeylerinden kaçınır.

Üzgünüz, gönderinizden daha kısa, umarım bunu ilginç bulursunuz ...


Güzel cevap! Bu ileti dizisi biraz trafik çekiyor gibi görünüyor, ne yazık ki diğer insanlar mimarilerini tanımlamak için zamanları olmadığını veya katılmamak için başka nedenleri olmadığını düşünüyorlar.

19

Günümüzde İdeal Java Tabanlı Web Geliştirme Teknolojileri.

Web Katmanı:

HTML + CSS + Ajax + JQuery

RESTFul Web Denetleyicisi / İşlem / Talep İşleme Katmanı:

Oyun Çerçevesi

İş Mantığı / Hizmet Katmanı:

Saf Java Kodunu olabildiğince uzun süre kullanın. Burada web servislerinin füzyonu yapılabilir.

XML / JSon Veri Dönüşüm Katmanı:

XMLTool (Google Kodunda Ara), JSoup, Google GSon, XStream, JOOX (Google Kodunda Ara)

Kalıcılık Katmanı:

CRUD: JPA veya SienaProject veya QueryDSL / Karmaşık Sorgular: JOOQ, QueryDSL


9

İşte benim 5 sentim

Sunum

Android, Angular.JS WebClient, OAUTHv2

API

REST, Jersey (JAX-RS), Jackson (JSON de- / serileştirme), DTO nesneleri (iş mantığı modellerinden farklı)

İş mantığı

DI ve Olay işleme için yay. Model nesnelerin DDD-ish yaklaşımı. Daha uzun süre çalışan işler, çalışan modüllerinde SQS ile kaldırılır.

DAO

Varlıkları depolamak için Spring JDBC şablonlarına sahip depo modeli. Sıralı Listeleri kullanarak Lider Tabloları için Redis (JEDIS). Token Store için Memcache.

Veri tabanı

MySQL, Memcached, Redis


Bu bizim projelerimizde de takip ettiklerimize benzer bir şey! Ayrıca iş akışı için JBPM. Neden bahar yok merak ediyorum?
ininprsr

Mevcut arşivimizle bir güncelleme yapmalıyım: Şu anda veri erişim katmanı için Spring DI ve JDBC şablonlarını kullanıyoruz.
Pepster

6

Projemizde takip ettiklerimiz:

Ön Uç Teknolojisi

  • AngularJS
  • HTML5
  • css3
  • Javascript
  • Önyükleme 3

API

  1. DİNLENME
  2. JERSEY (JAX-RS)
  3. EMİN OLABİLİRSİNİZ
  4. BAHAR ÇİZME
  5. Jackson
  6. bahar güvenliği

İş mantığı

  • BAHAR VERİLERİ

  • SPRING verileri MongoDB

Veri tabanı

  • MongoDB

Sunucu (Önbelleğe almak için)

  • Redis

4

Hala olağan Struts-Spring-Hibernate yığınını kullanıyoruz.

Gelecekteki uygulamalar için, Flex ön uçlu Spring Web Flow + Spring MVC + Hibernate veya Spring + Hibernate + Web Services'i araştırıyoruz.

Mimarimizin ayırt edici bir özelliği modülerleşmedir. Veritabanında bazıları 3 ila en fazla 30 tabloyla başlayan bir dizi modülümüz var. Modüllerin çoğu iş ve web projelerinden oluşur. İş projesi, iş ve kalıcılık mantığını tutarken, web sunum mantığını tutar.
Mantıksal düzeyde, üç katman vardır: İşletme, Sebat ve Sunum.
Bağımlılıklar:
Sunum, İş ve Sürekliliğe bağlıdır.
Kalıcılık İşletmeye bağlıdır.
İş diğer katmanlara bağlı değildir.

İş projelerinin çoğunun üç tür arabirimi vardır (not: GUI değil, programatik bir java arabirim katmanıdır).

  1. Sunumun istemci olarak kullandığı arayüz
  2. Diğer modüllerin, modülün istemcisi olduklarında kullandıkları arayüz.
  3. Modülün yönetimsel amaçları için kullanılabilen arayüz.

Genellikle 1, 2'yi genişletir. Bu şekilde, modülün bir uygulamasını diğeriyle değiştirmek kolaydır. Bu, farklı müşterilere uyum sağlamamıza ve daha kolay entegre olmamıza yardımcı olur. Bazı müşteriler yalnızca belirli modülleri satın alacak ve zaten sahip oldukları işlevleri entegre etmemiz gerekiyor. Arayüz ve uygulama katmanı ayrıldığından, bağımlı modülleri etkilemeden o belirli müşteri için reklam hock modülü uygulamasını hayata geçirmek kolaydır. Ve Spring Framework, farklı uygulamaları enjekte etmeyi kolaylaştırır.

İş katmanımız POJO'lara dayanmaktadır. Gözlemlediğim bir eğilim, bu POJO'ların DTO'lara benzemesidir. Anemik alan modelinden muzdaripiz . Bunun neden olduğundan tam olarak emin değilim, ancak modüllerimizin çoğunun problem etki alanının basitliğinden, işin çoğu CRUD'den veya geliştiricilerin mantığı başka bir yere yerleştirmeyi tercih etmesinden kaynaklanıyor olabilir.


3

İşte üzerinde çalıştığım bir web mimarisi daha:

Önemli bir gereksinim, uygulamanın cep telefonlarını / diğer cihazları desteklemesi gerektiğiydi. Uygulama aynı zamanda teknoloji seçeneklerindeki değişikliklere göre genişletilebilir veya esnek olmalıdır.

Sunum Katmanı:

  • JSP / JQuery (İstemci tarafı MVC)
  • Yerel Android
  • Yerel iPhone
  • Mobil web (HTML5 / CSS3 / Duyarlı tasarım)

  • Spring REST Kontrolörleri (JAX-RS olarak değiştirilebilir)

İşletme Hizmeti Katmanı:

Spring @Service (Stateless EJB olarak değiştirilebilir)

Veri Erişim Katmanı:

Spring @Repository (Stateless EJB olarak değiştirilebilir)

Kaynak Katmanı:

Hazırda Bekletme (JPA) varlıkları (Herhangi bir ORM ile değiştirilebilir)

Bu mimariyi takip eden kitap hakkında daha fazla bilgiyi burada bulabilirsiniz .


2

IMHO, çoğumuzun ortak bir paydası var. En azından arka planda, bir çeşit IOC / DI kapsayıcımız ve bir kalıcılık çerçevemiz var. Şahsen bunun için Guice ve Mybatis kullanıyorum. Farklılıklar, görünüm / kullanıcı arayüzü / sunum katmanını nasıl uyguladığımızdadır. Burada 2 ana seçenek vardır (daha fazla olabilir) .. Eylem tabanlı (denetleyicilere eşlenen URL'ler) ve bileşen tabanlı. Şu anda bileşen tabanlı sunum katmanı kullanıyorum (wicket kullanarak). URL'ler ve denetleyiciler yerine bileşenleri ve olayları kullandığım bir masaüstü ortamını mükemmel bir şekilde taklit ediyor. Şu anda bu URL denetleyici mimarisine geçmem için bir neden arıyorum (işte bu şekilde bu sayfaya geldim). Neden RESTful ve Stateless mimariler hakkındaki heyecan.

Bu soruyu kısaca cevaplamak için: Guice IOC konteynerinin üzerine bileşen odaklı bir çerçeve kullanarak durum bilgisi olan web uygulamaları yazıyorum ve Mybatis kullanarak verileri ilişkisel veritabanına koyuyorum.


1

Biraz farklı ve burada daha modüler java mimarisi olduğunu iddia ediyorum. Sahibiz:

  1. Yay WS / Dinlenme / JSP ön uç
  2. İş hizmeti mantığı için, sunum katmanı mantığının yanı sıra Spring işlemlerini içeren Spring MVC
  3. Bileşen hizmet iletişim arayüzü, iş hizmetleri tarafından EJB üzerinden arandı. EJB'ler, Spring işlemlerine katılabilen kendi işlem sınırlarını belirler.
  4. Bileşen servis uygulamaları, yine Spring bileşenleri
  5. Entegrasyon katmanı, veritabanı entegrasyonları için MyBatis, web servis entegrasyonları için Spring WS, diğer hizmetler için diğer entegrasyon teknolojileri
  6. Diğer sunuculardaki ana bilgisayarlar, veritabanları, diğer hizmetler ...

Yukarıdakilere ek olarak, tüm hizmetler için ortak işlevsellik sağlayıcısı olan paylaşılan kitaplık modüllerine sahibiz.

Farklı katmanların kullanılması, tam ayrıştırma ve ihtiyacımız olan modülerlik sağlar. Ayrıca Spring'in yanı sıra Java EE'nin gücünden tam olarak yararlanabiliyoruz. Örneğin, gerekirse ön uç için JSF kullanmamızı engelleyen hiçbir şey yoktur.

OP'nin örnek mimarisiyle karşılaştırıldığında, bence bu, bir bükülme ile de olsa, üç yerine dört ana katmana sahip olarak tanımlanabilir.


0

Bu katı yönetici modelini kullanan projeler üzerinde çalıştım. Tarihsel olarak, her şeyin düzgün bir kutuya sığdığı katı hiyerarşinin büyük bir savunucusuydum. Kariyerimde ilerledikçe birçok durumda bunun zorlandığını görüyorum. Uygulama tasarımına yönelik daha çevik bir zihniyet benimsemenin daha iyi bir ürüne yol açacağına inanıyorum. Bununla kastettiğim, eldeki sorunu çözen bir sınıflar kümesi oluşturmaktır. "Şunun ve bunun için bir yönetici mi oluşturdun?" Demek yerine.

Üzerinde çalıştığım mevcut proje, Spring MVC ve RestEasy JSON / Ajax çağrılarının birleşiminden oluşan bir web uygulaması. Denetleyicilerimize gömülü sunucu tarafında, doğrudan Veritabanı erişimi, bazı EJB erişimi ve bazı SOAP tabanlı web hizmeti çağrıları için JPA / Hibernate ile duyarlı bir cephe tabanlı veri katmanı bulunur. Tüm bunları birbirine bağlamak, neyin JSON olarak serileştirileceğini ve istemciye geri döneceğini belirleyen bazı özel java denetleyici kodudur.

Unix Tasarım Felsefesinin "Daha Kötüsü Daha İyi" fikrini benimsemek yerine, birleşik bir model oluşturmak için neredeyse hiç zaman harcamıyoruz. Çizgilerin dışını renklendirmek ve mantıklı bir şey inşa etmek, bir grup katı tasarım kuralına uyan bir şey inşa etmekten çok daha iyidir.


0

Web Uygulama Mimarisindeki bileşenler şunları içerir:

1: Tarayıcı: İstemci etkileşimi

        HTML
        JavaScript
        Stylesheet

2: İnternet

3: Web sunucusu

        CSS
        Image
        Pages(Java render )

4: Uygulama Sunucusu

        App Webapp (Java interaction)
        Others WebApps

5: Veritabanı Sunucusu

        Oracle, SQL, MySQL

6: Veriler

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.