簡體   English   中英

除了EAR和EJB之外,我從Java EE應用服務器獲得了什么,而我沒有像Tomcat那樣進入servlet容器?

[英]Besides EAR and EJB, what do I get from a Java EE app server that I don't get in a servlet container like Tomcat?

我們使用Tomcat來托管基於WAR的應用程序。 我們是與servlet容器兼容的J2EE應用程序,但org.apache.catalina.authenticator.SingleSignOn除外。

我們被要求遷移到商業Java EE應用服務器。

  1. 改變我看到的第一個缺點是成本。 無論應用服務器的收費是多少,Tomcat都是免費的。
  2. 其次是復雜性。 我們不使用EJB或EAR功能(當然不是,我們不能),並且沒有錯過它們。

那么我沒有看到的好處是什么?

我沒有提到的缺點是什么?


提到的是......

  1. JTA - Java Transaction API - 我們通過數據庫存儲過程控制事務。
  2. JPA - Java持久性API - 我們使用JDBC和再次存儲過程來持久化。
  3. JMS - Java消息服務 - 我們使用XML over HTTP進行消息傳遞。

這很好,請多多!

當我們以Java EE 6為目標開始將Apache Tomcat認證為Apache TomEE時 ,為了最終傳遞Java EE 6 TCK,我們必須填補一些空白。

不是一個完整的列表,但有些亮點即使有現有答案也可能不明顯。

沒有TransactionManager

任何經過認證的服務器都必須進行事務管理。 在任何Web組件(servlet,過濾器,監聽器,jsf托管bean)中,您應該能夠像這樣注入UserTransaction

  • @Resource UserTransaction transaction;

您應該能夠使用javax.transaction.UserTransaction來創建事務。 您在該交易范圍內觸及的所有資源都應該在該交易中注冊。 這包括但不限於以下對象:

  • javax.sql.DataSource
  • javax.persistence.EntityManager
  • javax.jms.ConnectionFactory
  • javax.jms.QueueConnectionFactory
  • javax.jms.TopicConnectionFactory
  • javax.ejb.TimerService

例如,如果在servlet中啟動事務,則:

  • 更新數據庫
  • 將JMS消息發送到主題或隊列
  • 創建一個Timer,以便稍后進行工作

..然后其中一個失敗或你只是選擇在UserTransaction上調用rollback() ,然后撤消所有這些事情。

沒有連接池

要非常清楚,有兩種連接池:

  • 事務感知連接池
  • 非事務性感知連接池

Java EE規范並不嚴格要求連接池,但是如果您有連接池,它應該是事務感知的,否則您將丟失事務管理。

這意味着什么基本上:

  • 同一事務中的每個人都應該從池中具有相同的連接
  • 在事務完成(提交或回滾)之前,不管是否有人在DataSource上調用close()或任何其他方法,都不應將連接返回到池。

在Tomcat中用於連接池的公共庫是commons-dbcp。 我們也希望在TomEE中使用它,但是它不支持事務感知連接池,所以我們實際上將這個功能添加到commons-dbcp(yay,Apache)中,並且它是commons-dbc 1.4版本。

注意,將commons-dbcp添加到Tomcat仍然不足以獲得事務連接池。 您仍然需要事務管理器,您仍然需要容器來執行通過Synchronization對象注冊與TransactionManager連接的管道。

在Java EE 7中,有人談到添加標准方法來加密數據庫密碼,並將它們與應用程序打包在一個安全文件或外部存儲中。 這將是Tomcat不支持的另一項功能。

沒有安全集成

Web服務安全性,JAX-RS SecurityContext,EJB安全性,JAAS登錄和JAAC都是安全概念,即使您單獨添加像CXF,OpenEJB等庫,默認情況下也不會在Tomcat中“連接”。

當然,這些API都假定在Java EE服務器中協同工作。 我們必須做很多工作才能讓所有這些合作並在Tomcat Realm API之上進行,以便人們可以使用所有現有的Tomcat Realm實現來驅動他們的“Java EE”安全性。 它仍然是Tomcat的安全性,它只是非常好地集成。

JPA集成

是的,您可以將JPA提供程序放入.war文件中,並在沒有Tomcat幫助的情況下使用它。 使用這種方法你不會得到:

  • @PersistenceUnit EntityManagerFactory注入/查找
  • @PersistenceContext EntityManager注入/查找
  • EntityManager連接到事務感知連接池
  • JTA管理的EntityManager支持
  • 擴展的持久化上下文

JTA-Managed EntityManager基本上意味着同一事務中希望使用EntityManager兩個對象都將看到相同的EntityManager並且不需要顯式傳遞EntityManager 所有這些“傳遞”都是由容器完成的。

這是如何實現的? 很簡單,你從容器中獲得的EntityManager是假的。 這是一個包裝。 當您使用它時,它會在當前事務中查找真實的EntityManager並將調用委托給該EntityManager 這就是神秘的EntityManager.getDelegate()方法的原因,因此用戶可以在需要時使用真正的 EntityManager並使用任何非標准API。 當然,這樣做非常謹慎,並且永遠不會保留對委托EntityManager的引用,否則您將發生嚴重的內存泄漏。 通常在事務完成時刷新,關閉,清理和丟棄委托EntityManager 如果您仍然持有引用,則將阻止該EntityManager垃圾收集以及它可能包含的所有數據。

  • 保持對從容器中獲取的EntityManager的引用始終是安全的
  • 保持對EntityManager.getDelegate()的引用是不安全的
  • 要非常小心抱着一個參考EntityManager您通過創建自己EntityManagerFactory -你是100%負責其管理。

CDI集成

我不想過度簡化CDI,但我發現它有點太大了很多人都沒有認真看待 - 對於很多人而言,這是“某一天”的名單:)所以這里只是一些亮點我認為一個“網絡人”會想知道。

你知道所有的推桿和讓你在一個典型的網絡應用程序嗎? 整天把東西拉進HttpSession 使用String作為鍵並連續地從HttpSession獲取對象。 您可能會使用實用程序代碼為您執行此操作。

CDI也有這個實用程序代碼,它被稱為@SessionScoped 任何使用@SessionScoped注釋的對象都會在HttpSession為您進行放置和跟蹤。 您只需通過@Inject FooObject請求將對象注入到Servlet中,CDI容器將以我描述EntitityManager的事務跟蹤的方式跟蹤“真實”FooObject實例。 Abracadabra,現在你可以刪除一堆代碼:)

HttpServletRequest上執行任何getAttributesetAttribute 好吧,你也可以用@RequestScoped以同樣的方式刪除它。

當然還有@ApplicationScoped來消除你可能在ServletContext上做的getAttributesetAttribute調用

為了使事情變得更酷,任何像這樣跟蹤的對象都可以實現一個@PostConstruct ,它在創建bean時被調用,而@PreDestroy方法在所述“范圍”完成時被通知(會話完成,請求結束,該應用程序正在關閉)。

CDI可以做更多,但這足以讓任何人想重新編寫一個舊的webapp。

一些挑剔的事情

Java EE 6中添加了一些在Tomcats駕駛室中未添加的東西。 他們不需要大的解釋,但確實占了“填補空白”的很大一部分。

  • 支持@DataSourceDefinition
  • 支持全局JNDI( java:globaljava:appjava:module
  • Enum注射來自@Resource MyEnum myEnum
  • 通過@Resource Class myPluggableClass和類注入
  • 支持@Resource(lookup="foo")

小點,但以可移植的方式在應用程序中定義DataSource ,在webapps之間共享JNDI條目,並且具有簡單的權力來說“看起來這個並注入它”是非常有用的。

結論

如上所述,不是一個完整的清單。 沒有提到EJB,JMS,JAX-RS,JAX-WS,JSF,Bean Validation和其他有用的東西。 但是,當人們談論Tomcat是什么和不是什么時,至少對事物的一些想法經常被忽視。

另請注意,您可能認為“Java EE”可能與實際定義不匹配。 使用Web Profile,Java EE已經縮減。 這是故意解決“Java EE太重而且我不需要所有這些”。

如果您將EJB從Web配置文件中刪除,那么這就是您剩下的內容:

  • Java Servlets
  • Java ServerPages(JSP)
  • Java ServerFaces(JSF)
  • Java Transaction API(JTA)
  • Java持久性API(JPA)
  • Java上下文和依賴注入(CDI)
  • Bean驗證

這是一個非常有用的堆棧。

除非您需要適當的EJB,否則您不需要完整的堆棧J2EE服務器(商用或非商用)。

您可以擁有大多數J2EE功能(例如JTA,JPA,JMS,JSF),而沒有完整的堆棧J2EE服務器。 完整堆棧j2ee的唯一好處是容器將以聲明方式代表您管理所有這些。 隨着EJB3的出現,如果您需要容器管理服務,使用一個是件好事。

您也可以沒有成本的完整堆棧服務器,如Glasfish,Geronimo或JBoss。

您也可以使用嵌入式Glasfish運行嵌入式j2ee容器托管服務,例如,在Tomcat內部。

如果要使用會話bean,消息bean,為您精心管理的計時器bean,您可能需要EJB容器,即使使用群集和故障轉移也是如此。

我建議管理層根據功能需求考慮升級。 其中一些EJB容器可能很好地使用嵌入式Tomcat作為其Web服務器,因此給出了什么!

有些經理喜歡為事情買單。 讓他們考慮一個城市住房捐贈或只是去BEA。

如果要求您遷移到商業J2EE服務器,原因可能與J2EE堆棧無關,而是出於非技術考慮。

使用Tomcat無法獲得的商業J2EE產品可以獲得的一件事就是技術支持。

這可能不是您的考慮因素,具體取決於您的Web應用程序應滿足的服務級別。 當您嘗試找出Tomcat的問題時,您的應用程序是否可以關閉,或者這是一個主要問題?

成本不一定是一個缺點,因為有一些免費的J2EE服務器,例如JBoss和Glassfish。

您的問題假定(J2EE = Servlet + EJB + EAR)因此,如果您不使用EJB或EAR,那么使用Servlet容器之外沒有任何意義。 事實並非如此,J2EE包含的內容遠不止這些。 例子包括:

  • JTA - Java事務API
  • JPA - Java持久性API
  • JMS - Java消息傳遞規范
  • JSF - 用於構建組件之外的用戶界面的技術

干杯,唐納德

事實上,由於提供了大量的包和庫,因此無法將EJB容器提供給現有的servlet容器(ala Tomcat)。 因此,如果你想要任何這些功能,你可以讓它們“點菜”,以便將成本作為將該功能集成到你的應用程序的過程。

如果您現在沒有“遺漏”任何這些功能,那么從實際角度來看,您可能不需要它們。

總而言之,現代EJB容器非常好用,並且預先集成了所有這些服務,如果你想要它們,它們在某種程度上更容易使用。 有時將附近的功能放在手邊,足以讓人們在應用程序中探索它的潛力,而不是將功能的集成過程視為采用的障礙。

由於免費的EJB容器的質量,很難想象購買一個有用的東西,特別是考慮到你目前沒有真正的需求。

但是,我確實鼓勵你真正得到一個並玩它並探索平台。 Glassfish非常容易上手且非常好,並且應該輕松地按照你的WAR(或者進行非常小的調整)。

作為規則,當運行Tomcat與EJB容器之間時,問題是為什么不使用它? 專門針對Glassfish,我發現它比Tomcat更容易使用,它的主要區別在於它可以擁有比Tomcat更大的內存占用(特別是對於小型應用程序),但在大型應用程序中你甚至不會注意到。 對我來說,記憶命中並不是什么大問題,對於其他人而言,它可能是一個問題。

它為我提供了所有這些不錯功能的單一來源,而無需為第三方選項抓取網絡。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM