[英]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應用服務器。
那么我沒有看到的好處是什么?
我沒有提到的缺點是什么?
提到的是......
這很好,請多多!
當我們以Java EE 6為目標開始將Apache Tomcat認證為Apache TomEE時 ,為了最終傳遞Java EE 6 TCK,我們必須填補一些空白。
不是一個完整的列表,但有些亮點即使有現有答案也可能不明顯。
任何經過認證的服務器都必須進行事務管理。 在任何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中啟動事務,則:
..然后其中一個失敗或你只是選擇在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提供程序放入.war文件中,並在沒有Tomcat幫助的情況下使用它。 使用這種方法你不會得到:
@PersistenceUnit EntityManagerFactory
注入/查找 @PersistenceContext EntityManager
注入/查找 EntityManager
連接到事務感知連接池 EntityManager
支持 JTA-Managed EntityManager
基本上意味着同一事務中希望使用EntityManager
兩個對象都將看到相同的EntityManager
並且不需要顯式傳遞EntityManager
。 所有這些“傳遞”都是由容器完成的。
這是如何實現的? 很簡單,你從容器中獲得的EntityManager
是假的。 這是一個包裝。 當您使用它時,它會在當前事務中查找真實的EntityManager
並將調用委托給該EntityManager
。 這就是神秘的EntityManager.getDelegate()
方法的原因,因此用戶可以在需要時使用真正的 EntityManager並使用任何非標准API。 當然,這樣做非常謹慎,並且永遠不會保留對委托EntityManager
的引用,否則您將發生嚴重的內存泄漏。 通常在事務完成時刷新,關閉,清理和丟棄委托EntityManager
。 如果您仍然持有引用,則將阻止該EntityManager
垃圾收集以及它可能包含的所有數據。
EntityManager
的引用始終是安全的 EntityManager.getDelegate()
的引用是不安全的 EntityManager
您通過創建自己EntityManagerFactory
-你是100%負責其管理。 我不想過度簡化CDI,但我發現它有點太大了很多人都沒有認真看待 - 對於很多人而言,這是“某一天”的名單:)所以這里只是一些亮點我認為一個“網絡人”會想知道。
你知道所有的推桿和讓你在一個典型的網絡應用程序嗎? 整天把東西拉進HttpSession
? 使用String
作為鍵並連續地從HttpSession
獲取對象。 您可能會使用實用程序代碼為您執行此操作。
CDI也有這個實用程序代碼,它被稱為@SessionScoped
。 任何使用@SessionScoped
注釋的對象都會在HttpSession
為您進行放置和跟蹤。 您只需通過@Inject FooObject
請求將對象注入到Servlet中,CDI容器將以我描述EntitityManager
的事務跟蹤的方式跟蹤“真實”FooObject實例。 Abracadabra,現在你可以刪除一堆代碼:)
在HttpServletRequest
上執行任何getAttribute
和setAttribute
? 好吧,你也可以用@RequestScoped
以同樣的方式刪除它。
當然還有@ApplicationScoped
來消除你可能在ServletContext
上做的getAttribute
和setAttribute
調用
為了使事情變得更酷,任何像這樣跟蹤的對象都可以實現一個@PostConstruct
,它在創建bean時被調用,而@PreDestroy
方法在所述“范圍”完成時被通知(會話完成,請求結束,該應用程序正在關閉)。
CDI可以做更多,但這足以讓任何人想重新編寫一個舊的webapp。
Java EE 6中添加了一些在Tomcats駕駛室中未添加的東西。 他們不需要大的解釋,但確實占了“填補空白”的很大一部分。
@DataSourceDefinition
java:global
, java:app
, java:module
) @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配置文件中刪除,那么這就是您剩下的內容:
這是一個非常有用的堆棧。
除非您需要適當的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包含的內容遠不止這些。 例子包括:
干杯,唐納德
事實上,由於提供了大量的包和庫,因此無法將EJB容器提供給現有的servlet容器(ala Tomcat)。 因此,如果你想要任何這些功能,你可以讓它們“點菜”,以便將成本作為將該功能集成到你的應用程序的過程。
如果您現在沒有“遺漏”任何這些功能,那么從實際角度來看,您可能不需要它們。
總而言之,現代EJB容器非常好用,並且預先集成了所有這些服務,如果你想要它們,它們在某種程度上更容易使用。 有時將附近的功能放在手邊,足以讓人們在應用程序中探索它的潛力,而不是將功能的集成過程視為采用的障礙。
由於免費的EJB容器的質量,很難想象購買一個有用的東西,特別是考慮到你目前沒有真正的需求。
但是,我確實鼓勵你真正得到一個並玩它並探索平台。 Glassfish非常容易上手且非常好,並且應該輕松地按照你的WAR(或者進行非常小的調整)。
作為規則,當運行Tomcat與EJB容器之間時,問題是為什么不使用它? 專門針對Glassfish,我發現它比Tomcat更容易使用,它的主要區別在於它可以擁有比Tomcat更大的內存占用(特別是對於小型應用程序),但在大型應用程序中你甚至不會注意到。 對我來說,記憶命中並不是什么大問題,對於其他人而言,它可能是一個問題。
它為我提供了所有這些不錯功能的單一來源,而無需為第三方選項抓取網絡。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.