JBoss与Tomcat的Spring MVC - 优点/实践

Kev*_*ave 13 java jboss spring application-server web-container

好的.这又是一个行业惯例问题.

  • Tomcat = Web容器
  • JBoss,WebLogic等=内置Web容器的应用服务器(对于JBoss,其分叉的Tomcat)

Spring不需要像JBoss这样的Application Server.如果我们使用JMS等企业服务,我们可以使用RabbitMQ,ApacheMQ等独立系统.

  1. 问题是为什么人们仍然将JBoss和其他Application Serves用于纯粹的基于弹簧的应用程序?
  2. 通过使用应用程序服务器,Spring可以使用哪些优势?像对象池?Application Server提供哪些特定优势?这些是如何配置的?
  3. 如果不是春天,为什么其他目的应用程序服务器用于Spring/Hibernate等堆栈?(用例)

Phi*_*all 6

实际上我会说,监听JMS可能是应用服务器的最佳理由.独立消息代理无法解决问题,因为您仍需要一个正在侦听消息的组件.最好的方法是使用MDB.理论上,您可以使用Springs MessageListenerContainer.然而,这有一些缺点,例如JMS只支持阻塞读取,因此Spring需要启动它自己的线程,这完全不受支持(即使在Tomcat中)并且可能破坏事务,安全性,命名(JNDI)和类加载(这反过来可能会破坏)远程).JCA资源适配器可以随意执行任何操作,包括通过WorkManager启动线程.可能除了JMS(或其他目标)之外还使用数据库,此时您需要XA事务和JTA,换句话说就是应用程序服务器.是的,您可以将其修补到servlet容器中,但是这一点与应用程序服务器无法区分.

恕我直言,反对应用服务器的最大原因是,在规范发布之后需要数年(这反过来需要数年时间),直到服务器实施规范并解决了最严重的错误.直到现在,就在即将发布EE 7之前,我们已经开始出现EE 6服务器,这些服务器并没有完全充满漏洞.有些供应商不再修复他们的EE 6系列中的错误,因为他们已经忙于即将推出的EE 7系列,这一点很滑稽.

编辑

对最后一段的详细解释:

许多地方的Java EE依赖于所谓的上下文信息.未明确作为参数从服务器/容器传递给应用程序但隐式"存在"的信息.例如,当前用户进行安全检查.当前的交易或连接.当前应用程序用于查找类以延迟加载代码或反序列化对象.或者用于进行JNDI查找的当前组件(servlet,EJB,...).所有这些信息都在服务器/容器在调用组件(servlet,EJB,...)之前设置的线程本地中.如果您创建自己的线程,则服务器/容器不知道它们,并且依赖于此信息的所有功能都不再起作用.你可以通过不在你产生的线程中使用任何这些功能来逃避这一点.

一些链接

http://www.oracle.com/technetwork/java/restrictions-142267.html#threads http://www.ibm.com/developerworks/websphere/techjournal/0609_alcott/0609_alcott.html#spring-4

如果我们检查Servlet 3.0规范,我们会发现:

2.3.3.3异步处理

Java Enterprise Edition的功能,例如第15-174页的第15.2.2节"Web应用程序环境"和第15-176页的第15.3.1节"EJBTM调用中的安全标识的传播"仅适用于执行初始请求的线程或者通过AsyncContext.dispatch方法将请求分派给容器时.通过AsyncContext.start(Runnable)方法,直接在响应对象上运行的其他线程可以使用Java Enterprise Edition功能.

这与异步处理有关,但同样的限制适用于自定义线程.

public void start(Runnable r) - 此方法使容器可能从托管线程池调度线程,以运行指定的Runnable.容器可以将适当的上下文信息传播到Runnable.

同样,异步处理但相同的限制适用于自定义线程.

15.2.2 Web应用程序环境

当在开发人员创建的线程上执行时,此类型的servlet容器应支持此行为,但目前不需要这样做.这种要求将在本规范的下一版本中添加.开发人员应注意,不建议使用应用程序创建的线程,因为它不可移植.

非便携式意味着它可以在一个服务器中但不能在另一个服务器中.

如果要在MDB外部使用JMS接收消息,可以使用以下四种方法javax.jms.MessageConsumer:

  • #receiveNoWait()你可以在一个容器线程中,它不会阻止,但它就像偷看.如果没有消息,则返回null.这不太适合收听消息.
  • #receive(long)你可以在一个容器线程中,它确实阻止.你通常不想在容器线程中阻止等待.再次不太适合收听消息.
  • #receive(),这可能无限期地阻止.再次不太适合收听消息.
  • #setMessageListener()这就是你想要的,当你收到消息时你得到一个回调.但是,除非库可以挂钩到应用程序服务器,否则这将不是容器线程.进入应用程序服务器的钩子只能通过JCA到资源适配器.

所以,是的,它可能会起作用,但它不能保证,并且有很多事情可能会破坏.

  • `然而,这有一些缺点,例如JMS只支持阻塞读取,因此Spring需要启动它自己的线程,这完全不受支持(即使在Tomcat中)并且可以破坏事务,安全性,命名(JNDI)和类加载(这反过来可以打破遥控器.)"你能告诉我你在哪里找到这个吗?我相信有些人在没有App Server的情况下使用Spring和独立的消息代理.试图找出是否有人在任何地方提出这个问题.不是说你错了!:-)试图获得更多的洞察力. (2认同)