Evet, hem CDI hem de EJB'yi özgürce karıştırabilir ve harika sonuçlar elde edebilirsiniz. Kullanıyormuşsunuz gibi görünüyor @WebService
ve @Schedule
bunlar karışıma EJB eklemek için iyi nedenlerdir.
Orada çok fazla kafa karışıklığı var, bu yüzden burada EJB ve CDI hakkında birbirleriyle ilişkili olduklarından bazı genel bilgiler var.
EJB> = CDI
EJB'ler Not olduğunu vardır bu nedenle CDI fasulye ve CDI tüm avantajlarına sahip. Tersi (henüz) doğru değil. Bu nedenle, mantık gerçekten garip bir denklem olan "EJB + CDI vs CDI" anlamına geldiği için kesinlikle "EJB vs CDI" şeklinde düşünme alışkanlığı edinmeyin.
Java EE'nin gelecekteki sürümlerinde, bunları uyumlu hale getirmeye devam edeceğiz. Ne hizalama düzeneğinin sadece olmadan, insanlar zaten neler yapabileceğini yapmak için izin veriyor @Stateful
, @Stateless
ya da @Singleton
üstündeki ek açıklamadır.
Uygulama Koşullarında EJB ve CDI
Sonuçta, EJB ve CDI, proxy'li bileşenler olma temel tasarımını paylaşır. Bir EJB veya CDI fasulyesine referans aldığınızda, bu gerçek fasulye değildir. Aksine, size verilen nesne sahte (bir vekil). Bu sahte nesne üzerinde bir yöntem çağırdığınızda, çağrı, aramayı durdurucular, dekoratörler vb. Aracılığıyla gönderecek ve ayrıca herhangi bir işlem veya güvenlik kontrolüyle ilgilenecek konteynere gider. Tüm bunlar yapıldıktan sonra, çağrı nihayet gerçek nesneye gider ve sonuç proxy aracılığıyla arayana geri gönderilir.
Aradaki fark yalnızca çağrılacak nesnenin nasıl çözüldüğünde ortaya çıkar. "Çözüldü" ile basitçe, kapsayıcının çağırmak için gerçek örneği nerede ve nasıl aradığını kastediyoruz.
CDI'da kapsayıcı, temelde belirli bir süre (istek @RequestScoped
başına, HTTP Oturumu @SessionScoped
başına, uygulama başına @ApplicationScoped
, JSF İletişimi @ConversationScoped
veya özel kapsam uygulamanıza göre) yaşayan bir karma harita olacak bir "kapsam" içinde arar .
EJB'de, çekirdek türdeyse, kapsayıcı bir karma haritaya da bakar @Stateful
. Bir @Stateful
fasulye ayrıca, kapsamdaki diğer tüm çekirdeklerle birlikte yaşamasına ve ölmesine neden olan yukarıdaki kapsam ek açıklamalarından herhangi birini kullanabilir. EJB'de @Stateful
esasen "herhangi bir kapsamlı" fasulyedir. @Stateless
Temelde bir örnek havuzu - Bir çağırma süresince havuzundan bir örneğini olsun. @Singleton
esasen@ApplicationScoped
Yani temel düzeyde, bir "EJB" fasulyesiyle yapabileceğiniz her şeyi bir "CDI" fasulyesi ile yapabilmelisiniz. Örtülerin altında onları birbirinden ayırmak çok zor. Örneklerin nasıl çözüldüğü dışında tüm su tesisatı aynıdır.
Konteynırın bu proxy'yi yaparken sunacağı hizmetler açısından şu anda aynı değiller, ancak söylediğim gibi bunun üzerinde Java EE özellik seviyesinde çalışıyoruz.
Performans notu
Sahip olabileceğiniz "hafif" veya "ağır" zihinsel görüntülere aldırmayın. Hepsi pazarlama. Çoğunlukla aynı iç tasarıma sahiptirler. CDI örnek çözünürlüğü belki biraz daha karmaşıktır çünkü biraz daha dinamik ve bağlamsaldır. EJB örnek çözünürlüğü, kıyaslandığında oldukça statik, aptal ve basittir.
Size TomEE'deki bir uygulama perspektifinden söyleyebilirim, bir EJB'yi çağırmakla bir CDI çekirdeğini çağırmak arasında sıfır performans farkı var.
Varsayılan olarak POJO'lar, ardından CDI, ardından EJB
Elbette hiçbir faydası olmadığında CDI veya EJB kullanmayın. Enjeksiyon, olaylar, önleyiciler, dekoratörler, yaşam döngüsü takibi ve benzeri şeyler istemeye başladığınızda CDI ekleyin. Çoğu zaman bu.
Bu özelliklerinin dışında, kullanışlı konteyner hizmetleri bir numara size CDI da fasulye ekleyerek EJB yaparsanız sadece kullanma seçeneğine sahip bulunmaktadır @Stateful
, @Stateless
ya @Singleton
buna.
İşte EJB'leri ne zaman kırdığımın kısa bir listesi.
JAX-WS'yi kullanma
Bir JAX-WS'yi açığa çıkarmak @WebService
. Tembelim. Aynı @WebService
zamanda bir EJB olduğunda, onu listelemeniz ve web.xml
dosyada sunucu uygulaması olarak eşleştirmeniz gerekmez . Bu benim için iş. Ayrıca, aşağıda belirtilen diğer işlevlerden herhangi birini kullanma seçeneğine de sahip oluyorum. Bu yüzden benim için hiç düşünmeden.
Yalnızca @Stateless
ve @Singleton
yalnızca kullanılabilir.
JAX-RS kullanımı
Aracılığıyla bir JAX-RS kaynağını açığa çıkarma @Path
. Hâlâ tembelim. RESTful hizmeti de bir EJB olduğunda, yine otomatik keşif alırsınız ve bunu bir JAX-RS Application
alt sınıfına veya buna benzer bir şeye eklemeniz gerekmez . Ayrıca, @WebService
aşağıda belirtilen harika işlevlerden herhangi birini kullanmak istersem veya kullanmak istersem, aynı fasulyenin aynısını gösterebilirim .
Yalnızca @Stateless
ve @Singleton
yalnızca kullanılabilir.
Başlangıç mantığı
Başlangıçta yükle @Startup
. Şu anda CDI'da buna eşdeğer bir şey yok. Her nasılsa AfterStartup
kapsayıcı yaşam döngüsüne bir olay gibi bir şey eklemeyi kaçırdık . @ApplicationScoped
Bunu yapsaydık, onu dinleyen bir fasulyeye sahip olabilirdiniz ve bu, bir @Singleton
ile ile aynı şey olurdu @Startup
. CDI 1.1 listesinde.
Uygun @Singleton
yalnızca.
Paralelde Çalışma
@Asynchronous
yöntem çağrısı. Herhangi bir sunucu tarafı ortamında iş parçacığı başlatmak bir hayırdır. Çok fazla iş parçacığına sahip olmak ciddi bir performans katilidir. Bu açıklama, kapsayıcının iş parçacığı havuzunu kullanarak yaptığınız şeyleri paralelleştirmenize olanak tanır. Bu harika.
Uygun @Stateful
, @Stateless
ve @Singleton
.
İş planlama
@Schedule
veya ScheduleExpression
temelde bir cron veya Quartz
işlevselliktir. Ayrıca çok harika. Çoğu kap, bunun için kapakların altında sadece Quartz kullanır. Ancak çoğu insan, Java EE'de planlama işinin işlemsel olduğunu bilmiyor! Bir veritabanını günceller ve ardından bazı işler planlarsanız ve bunlardan biri başarısız olursa, her ikisi de otomatik olarak temizlenir. Eğer EntityManager
devam çağrısı başarısız veya bir sorun yıkama var, iş un-zamanlamaya gerek yoktur. Yaşasın, işlemler.
Yalnızca @Stateless
ve @Singleton
yalnızca kullanılabilir.
EntityManager'ları bir JTA işleminde kullanma
İşlemlerle ilgili yukarıdaki not elbette bir JTA
yönetilen kullanmanızı gerektirir EntityManager
. Bunları düz "CDI" ile kullanabilirsiniz, ancak konteyner tarafından yönetilen işlemler olmadan UserTransaction
kesinleştirme / geri alma mantığını çoğaltarak gerçekten monoton hale gelebilir .
CDI, JSF dahil tüm Java EE bileşenlerine Temin @ManagedBean
, @WebServlet
, @WebListener
, @WebFilter
, vb @TransactionAttribute
açıklama, ancak, kullanılabilir @Stateful
, @Stateless
ve @Singleton
sadece.
JTA'nın yönetilmesini sağlamak EntityManager
EXTENDED
Yönetilen EntityManager
bir saklamanızı sağlar EntityManager
arasındaki açık JTA
işlemler ve kaybetmek önbelleğe alınmış verileri. Doğru zaman ve yer için iyi bir özellik. Sorumlu kullanın :)
Uygun @Stateful
yalnızca.
Kolay senkronizasyon
Senkronizasyona ihtiyacınız olduğunda, @Lock(READ)
ve @Lock(WRITE)
ek açıklamalar oldukça mükemmel. Eşzamanlı erişim yönetimini ücretsiz olarak almanızı sağlar. Tüm ReentrantReadWriteLock tesisatlarını atlayın. Aynı pakette, @AccessTimeout
vazgeçmeden önce bir iş parçacığının fasulye örneğine erişmek için ne kadar beklemesi gerektiğini söylemenize olanak tanır.
Sadece @Singleton
fasulyelerde mevcuttur.