2012-11-27 69 views
8

我正在开发一个项目,我们需要构建连接到一个数据库的几个“独立”模块。这些模块主要是后台业务流程,所以没有太多的前端。除了一个Web模块显示数据并允许基本的CRUD功能。为此,我们计划使用以下技术:Java EE vs Standalone

  • JPA2(使用Hibernate,JPA实现)
  • CDI(使用弹簧实现)
  • JSF2 + primefaces(我们的Web模块)

最初的计划是为每个模块创建一个jar文件(使用main方法),并通过服务包装器将其安装为(windows)服务。对于我们的Web模块,我们将使用Glassfish或JBoss来运行它。但是,最近Java EE出现在我们的脑海里。我们可以在Glassfish或JBoss等Java EE容器中运行我们的所有模块,而不仅仅是我们的Web模块。对于我们去Java EE的案例,有一些问题:

  1. Can/should we use CDI with spring?或者我们应该切换到EJB3?
  2. 当我们从容器中使用它而不是独立模块时,JPA会带来什么后果?有什么区别吗?
  3. 由于我们的大多数模块都与Web无关,因此在Java EE容器中运行它们仍然有意义吗?

回答

3

其他人指出了一些优点,因此如果您将后台进程部署到与您的Web应用程序相同的jvm中,这里有一些缺点。

  • 启动和停止运行Web模块的服务器意味着您启动和停止后台进程,这对您来说可能会或可能不会造成问题。
  • 如果后台进程消耗大量内存或cpu,那么您将与所有三个应用程序共享堆,这可能会影响您的Web应用程序,或者如果Web应用程序使用大量资源,可能会影响后台进程。
  • Web应用程序可能需要以可通过互联网访问的方式进行部署,但后台进程可能很乐意在没有任何访问权限的情况下运行。那么为什么如果你不需要将后台进程公开给互联网呢?
  • 当您升级应用程序服务器或框架或配置时,这意味着需要测试三件事情,如果后台进程独立运行,您可以在单独的发布周期将其升级到Web应用程序。
  • 在容器外部开发和测试代码更简单。在容器中运行后台进程意味着后台进程需要更复杂的开发环境,您必须等待服务器启动,然后根据容器资源启动,然后您必须模拟单元测试...等。

JPA在容器内部和外部是相同的。唯一的区别是你如何获得一个EntityManager,这可以通过Spring配置为在容器内和外都相同。 CDI应该可以在容器外运行。

主要区别在于你如何使用db进行交易,例如使用Spring交易与ejb交易。

更新: 要回答你的问题形成意见:在JPA EntityManager的不是线程安全的,从而在Java EE服务器会有每个线程每个持久单元一个实体管理器。实体管理器的创建和关闭由应用服务器为您管理。每个实体管理器都有一个缓存。可以配置跨越多个实体管理器的二级缓存。在容器外部运行时,您必须自己管理JPA实体管理器的数量,这取决于您想要的后台进程和事务边界中的线程数。如果你看一本名为“Pro JPA2”的书,有一节讨论容器内部或外部运行的细节。

在我的应用程序中,我没有后台进程,但每个需要实体管理器的类只需使用@PersistenceContext EntityManager em;注入,而spring会负责使其在容器内部和外部都工作。 Spring 3.1有一个称为profiles的特性,它使得在不改变一行代码的情况下在容器外部运行相同的代码是很简单的。我不是CDI用户,所以我不知道CDI是否具有与3.1版配置文件功能相同的功能。

+0

感谢您向我展示的缺点!关于使用JEE的entitymanager,我们不是只有1个实例,而不是独立的,每个JVM有1个实例(/模块)?这会对hibernate缓存产生影响吗? –

+0

为防万一有人认真对待这个问题,请注意,如果您只是使用两个不同的容器,一个用于网络的一个容器,几乎所有的缺点都会消失。实际上,每件事物都使用一个容器。与CDI,JPA统一标准容器的优点是什么不是巨大的。至于开发效率,eclipse也可以提供与java ee容器类似的转换。唯一需要修改的是关闭批量容器的http侦听器。只是说不要春天或任何非标准 - java ee 7已被批准,你会得到一大堆好东西。 – necromancer

+0

@RobeEleckers另外一个容器本质上是一个jvm,所以如果你只是关闭你正在运行一个批处理java进程的网络监听器。 – necromancer

1

这是有道理的应用服务器,而不是常见的原因如

1独立的Java程序),因为EJB3也是基于类似的概念,您可以使用CDI弹簧运行。 2)就JPA而言,除了如果您需要稍后向应用程序添加更多的卷以外,可以通过添加运行相同应用程序的更多计算机来添加负载 - 但请注意,这是非 - 因此它取决于业务需求做出选择 3)由于独立Java应用程序的内置安全性,可靠性,管理和可伸缩性,应用程序服务器赢得了独立应用程序的支持。

3

如果所有模块(批次+实时)都与一个产品相关,那么将它们捆绑在一起是一种好方法。所以这里是我的建议

  1. 把你所有的模块捆绑到一个耳朵。
  2. 使用Java EE 6并摆脱春天。 CDI旨在用于Java EE。对于批处理类型的操作,请尝试使用Asynchronous EJBs或MDB。

回答您的具体问题

  • 能/应该我们仍然使用CDI与春天?或者我们应该切换到EJB3?

CDI也可以在没有EJB的情况下使用。无论如何摆脱春天,因为我没有看到你的简单项目增值。

  • 当我们从一个容器中使用它而不是独立模块时,JPA的后果是什么?有什么区别吗?

除了您可以从JNDI获取数据源这一事实之外没有任何区别。

  • 由于我们的大多数模块都不是与网络相关的,因此在Java EE容器中运行它们仍然有意义吗?

是的,只要您没有看到任何性能问题,就可以将单个产品的批处理和实时方面捆绑在一起。

+0

是否可以在独立的Java应用程序中使用CDI? – amphibient

+0

您并没有真正解释为什么“只要您没有看到任何性能问题就将单个产品的批处理和实时方面捆绑在一起是合理的”,也就是说,这些好处与额外的复杂性级别相关联在独立的应用服务器中运行它。 – amphibient

+0

@ foampile相关模块通常依赖于相同的一组核心模块。所以将它们捆绑在一起是有道理的。我不确定在应用程序服务器上运行的复杂性是什么? MDB是用于异步处理的,它们在appserver的上下文中运行。 –