当前位置:  开发笔记 > 编程语言 > 正文

除了EAR和EJB之外,我从Java EE应用服务器获得了什么,我没有像Tomcat那样进入servlet容器?

如何解决《除了EAR和EJB之外,我从JavaEE应用服务器获得了什么,我没有像Tomcat那样进入servlet容器?》经验,为你挑选了2个好方法。

我们使用Tomcat来托管基于WAR的应用程序.我们是与servlet容器兼容的J2EE应用程序,但org.apache.catalina.authenticator.SingleSignOn除外.

我们被要求迁移到商业Java EE应用服务器.

    改变我看到的第一个缺点是成本.无论应用服务器的收费是多少,Tomcat都是免费的.

    其次是复杂性.我们不使用EJB或EAR功能(当然不是,我们不能),并且没有错过它们.

那么我没有看到的好处是什么?

我没有提到的缺点是什么?


提到的是......

    JTA - Java Transaction API - 我们通过数据库存储过程控制事务.

    JPA - Java持久性API - 我们使用JDBC和再次存储过程来持久化.

    JMS - Java消息服务 - 我们使用XML over HTTP进行消息传递.

这很好,请多多!



1> David Blevin..:

当我们以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,以便稍后进行工作

..然后其中的一件事情失败,或者你只是选择调用rollback()UserTransaction,那么所有的这些东西都被撤消.

没有连接池

要非常清楚,有两种连接池:

事务感知连接池

非事务性感知连接池

Java EE规范并不严格要求连接池,但是如果您有连接池,它应该是事务感知的,否则您将丢失事务管理.

这意味着什么基本上:

同一事务中的每个人都应该从池中具有相同的连接

在事务完成(提交或回滚)之前,不应该将连接返回到池,无论是否有人调用close()或者任何其他方法DataSource.

在Tomcat中用于连接池的公共库是commons-dbcp.我们也想在TomEE中使用它,但是它不支持事务感知连接池,所以我们实际上将这个功能添加到commons-dbcp(yay,Apache)中,并且它是commons-dbc 1.4版本.

注意,将commons-dbcp添加到Tomcat仍然不足以获得事务连接池.您仍然需要事务管理器,您仍然需要容器来执行与TransactionManagervia Synchronization对象注册连接的管道.

在Java EE 7中,有人提到添加标准方法来加密数据库密码,并将它们与应用程序打包在一个安全文件或外部存储中.这将是Tomcat不支持的另一项功能.

没有安全集成

Web服务安全性,JAX-RS SecurityContext,EJB安全性,JAAS登录和JAAC都是安全概念,即使您单独添加像CXF,OpenEJB等库,默认情况下也不会在Tomcat中"连接".

当然,这些API都假定在Java EE服务器中协同工作.我们必须做很多工作才能让所有这些合作并在Tomcat RealmAPI 之上进行,以便人们可以使用所有现有的Tomcat Realm实现来驱动他们的"Java EE"安全性.它仍然是Tomcat的安全性,它只是非常好地集成.

JPA集成

是的,您可以将JPA提供程序放入.war文件中,并在没有Tomcat帮助的情况下使用它.使用这种方法你不会得到:

@PersistenceUnit EntityManagerFactory 注入/查找

@PersistenceContext EntityManager 注入/查找

一个EntityManager挂接到一个事务感知连接池

JTA管理EntityManager支持

扩展的持久化上下文

JTA-Managed EntityManager基本上意味着同一事务中希望使用a的两个对象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.您只需要将对象注入到Servlet中@Inject FooObject,CDI容器将跟踪"真正的"FooObject实例,就像我描述的事务跟踪一样EntitityManager.Abracadabra,现在你可以删除一堆代码:)

做任何getAttributesetAttributeHttpServletRequest?好吧,你也可以用@RequestScoped同样的方式删除它.

当然还有就是@ApplicationScoped消除getAttributesetAttribute叫你可能会做的ServletContext

为了使事情变得更酷,任何像这样跟踪的对象都可以实现@PostConstruct在创建bean时调用的对象以及@PreDestroy在所述"范围"完成时要通知的方法(会话完成,请求结束,应用程序正在关闭)下).

CDI可以做更多,但这足以让任何人想重新编写一个旧的webapp.

一些挑剔的事情

Java EE 6中添加了一些在Tomcats驾驶室中未添加的东西.他们不需要大的解释,但确实占了"填补空白"的很大一部分.

支持 @DataSourceDefinition

全球JNDI支持(java:global,java:app,java: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验证

这是一个非常有用的堆栈.



2> Florin..:

除非您需要适当的EJB,否则您不需要完整的堆栈J2EE服务器(商用或非商用).

您可以拥有大多数J2EE功能(例如JTA,JPA,JMS,JSF),而没有完整的堆栈J2EE服务器.完整堆栈j2ee的唯一好处是容器将以声明方式代表您管理所有这些.随着EJB3的出现,如果您需要容器管理服务,使用一个是件好事.

您也可以没有成本的完整堆栈服务器,如Glasfish,Geronimo或JBoss.

您也可以使用嵌入式Glasfish运行嵌入式j2ee容器托管服务,例如,在Tomcat内部.

如果要使用会话bean,消息bean,为您精心管理的计时器bean,您可能需要EJB容器,即使使用群集和故障转移也是如此.

我建议管理层根据功能需求考虑升级.其中一些EJB容器可能很好地使用嵌入式Tomcat作为其Web服务器,因此给出了什么!

有些经理喜欢为事情买单.让他们考虑一个城市住房捐赠或只是去BEA.


读者注意,自这个答案以来,有些事情发生了变化 一个人甚至可以说*因为*这样的答案:)你现在可以通过网络配置文件获得少于"完整堆栈".现在有一个经过认证的Tomcat版本(TomEE),它与GlassFish或JBoss处于同一级别.CDI已被添加,并且在过去一两年中已被证明是Java EE的主要吸引力.
推荐阅读
yzh148448
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有