J2EE容器的理解 -- 让Spring JMS使用WebSphere的线程池

来源:互联网 发布:成都电影院 知乎 编辑:程序博客网 时间:2024/06/14 18:34

记得几个月前在解决一个SSL Handshake问题后感悟到WAS是一个J2EE容器的含义,近期的一个事情又加深了我对“容器”一词的感受。

项目的背景是用微服务架构重构一个十多年前开发的基于WAS的一个J2EE应用时。在重构过程中需要暂时性在该WAS应用上增加一个MQ进行侦听器,无需多想两种解决方案就浮现出来:传统过时的MDB(Message Driven Bean)和Spring JMS Container。对于以年轻人为主的团队来说,EJB无论如何都不会成为首选,毕竟那是十年前的技术流派了,大家只是听说过。所以自然而然地选择了后者–Spring JMS Container。

线上线下关于Spring的资料很丰富,所以实现一个需要的JMS Listener Container是很顺利的,最后就只剩下一个事务问题待解决。WebSphere提供了JTA的实现, 而Spring的事务管理器接口很简单,但是由于这是一个改造项目,业务逻辑很复杂,并且代码运行了很多年,所以任何一点代码改动都可能造成业务问题,结果就只能最大限度的保留现有代码。而该代码是原来是一个EJB(MDB)的一部分,通过EJB容器来获取一个JTA事务的,在把该代码移植到基于Spring的JMS Container时,我们仅仅把获取事务管理器的代码改成了通过JNDI来获取一个WebSphere上的JTA实例。一切看起来都是水到渠成。

但是部署到WebSphere上运行的时候却碰到了问题,错误提示该线程不是在WebSphere下的线程无法获取JNDI对象。问题来了,我们的应用不是部署在WebSphere上的吗?什么叫线程不在WebSphere里?这个问题一下子刺激了“WebSphere是容器”的理解,根本原因就是我们用的Spring的JMS Container是由Spring通过java线程池方式来创建的线程,这些线程是直接通过Java标准API建立的直接运行在JVM上的,对WebSphere而言是透明的,正是由于它不是运行在WebSphere的容器里,WebSphere容器本身的资源和服务对它也是透明的。明白了这个之后,解决办法就很简单了,在Spring里配置一下线程池,让它用WebSphere的线程池,比如wm/default。简单改动之后重新部署,问题解决。

补记:
关于J2EE容器的理解也让另一个问题的解决有了新的思路。

0 0