繁体   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