Java 使用JBoss与Tomcat的Spring MVC-优势/实践

Java 使用JBoss与Tomcat的Spring MVC-优势/实践,java,spring,jboss,application-server,web-container,Java,Spring,Jboss,Application Server,Web Container,好的。这又是一个行业实践的问题 Tomcat=Web容器 JBoss、WebLogic等=在其中包含Web容器的应用程序服务器(对于JBoss,是其分叉的Tomcat) Spring不需要像JBoss这样的应用服务器。如果我们使用JMS等企业服务,我们可以使用RabbitMQ、ApacheQ等独立系统 问题是为什么人们仍然使用JBoss和其他应用程序服务来开发纯基于spring的应用程序 通过使用应用服务器,Spring可以利用哪些优势?比如对象池?应用服务器提供了哪些具体优势?这些是如何配

好的。这又是一个行业实践的问题

  • Tomcat=Web容器
  • JBoss、WebLogic等=在其中包含Web容器的应用程序服务器(对于JBoss,是其分叉的Tomcat)
Spring不需要像JBoss这样的应用服务器。如果我们使用JMS等企业服务,我们可以使用RabbitMQ、ApacheQ等独立系统

  • 问题是为什么人们仍然使用JBoss和其他应用程序服务来开发纯基于spring的应用程序
  • 通过使用应用服务器,Spring可以利用哪些优势?比如对象池?应用服务器提供了哪些具体优势?这些是如何配置的
  • 如果不是spring,那么spring/Hibernate等堆栈使用应用服务器还有什么其他用途?(用例)

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

    IMHO反对应用服务器的最大原因是,规范发布后需要几年时间(反过来也需要几年),直到服务器实现规范并解决最严重的错误。直到现在,就在EE7即将发布之前,我们才发现EE6服务器开始出现,并没有完全被bug所困扰。有趣的是,一些供应商不再修复他们的EE6产品线中的bug,因为他们已经在忙于即将推出的EE7产品线

    编辑

    最后一段的详细解释:

    JavaEE在很多地方依赖于所谓的上下文信息。未作为参数从服务器/容器显式传递到应用程序,但隐式“在那里”的信息。例如,用于安全检查的当前用户。当前事务或连接。用于查找类以延迟加载代码或反序列化对象的当前应用程序。或用于执行JNDI查找的当前组件(servlet、EJB等)。所有这些信息都是服务器/容器在调用组件(servlet、EJB等)之前设置的线程局部变量。如果您创建自己的线程,那么服务器/容器就不知道这些线程,并且依赖于这些信息的所有功能都不再工作。您可以通过在生成的线程中不使用任何这些特性来避免这种情况

    一些链接

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

    2.3.3.3异步处理

    Java Enterprise Edition功能,如第15-174页的第15.2.2节“Web应用程序环境”和第15-176页的第15.3.1节“EJBTM调用中的安全标识传播”,仅对执行初始请求的线程可用,或者当请求通过AsyncContext.dispatch方法发送到容器时可用。Java Enterprise Edition的功能可以通过AsyncContext.start(Runnable)方法直接在响应对象上操作的其他线程使用

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

    public void start(Runnable r)-此方法导致容器分派线程(可能来自托管线程池)以运行指定的Runnable。容器可以将适当的上下文信息传播到Runnable

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

    15.2.2 Web应用程序环境

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

    不可移植意味着它可以在一台服务器上运行,但不能在另一台服务器上运行

    当您希望在MDB之外使用JMS接收消息时,可以在
    javax.JMS.MessageConsumer
    上使用四种方法:

    • #receiveNoWait()
      您可以在容器线程中对此进行访问,它不会阻塞,但就像偷看一样。如果没有消息,它只返回
      null
      。这不太适合听消息
    • #receive(long)
      您可以在容器线程中执行此操作,它确实会阻塞。您通常不想在容器线程中执行阻塞等待。还是不太适合听信息
    • #receive()
      ,这可能会无限期地阻塞。还是不太适合听信息
    • #setMessageListener()
      这就是您想要的,当消息到达时,您的系统将收到一个回调。但是,除非库能够钩住应用服务器,否则这将不是一个容器线程。应用程序服务器的挂钩只能通过JCA连接到资源适配器

    是的,它可能会工作,但不能保证,而且有很多东西可能会坏掉。

    我们正在使用JBoss而不是tomcat作为JNDI数据源和po