我正在创建一个Java EE应用程序,允许用户从Web界面添加/删除“socketinfo”表(存储在数据库中)。如果用户从Web界面启用“socketinfo”,则应用程序服务器必须为传入的数据包创建套接字侦听器并处理数据。如果用户禁用或删除“socketinfo”,则必须删除套接字侦听器。整个产品必须包含在一只耳朵中,并且最好是顺从的。我考虑过但遇到问题的一些方法是:
为套接字创建JCA资源适配器并使用MDB作为侦听器。我遇到的问题是,当用户添加MDB时,我无法弄清楚如何以编程方式为不同的套接字部署MDB。
创建一个@ Singleton / @ Service ejb,通过仔细同步管理守护程序线程。单例ejb可以注入业务层,以便在正确的工作流程中进行CRUD操作和套接字操作。这里的问题是,据说从EJB创建线程被认为是一种不好的做法,并且不符合规范(即使正确处理了单例生命周期并且有适当的同步机制?)。
将线程放在域模型中(另一个单例?)并让EJB使用该模型。这是所有这些中最糟糕的,因为应用程序服务器往往具有多个类加载器,一般来说容器支持较少,而且这样做会受到所有问题的影响2.患有此问题。
知道如何在Java EE中正确处理这种情况吗?
编辑:这个问题的扩展:假设我决定像ewernli在他的解决方案3中建议的那样解决这个问题,我在JCA(使用自定义界面添加内部线程)中做到这一点我不会得到什么来自(精心设计的)单身人士?虽然创建一个资源适配器看起来不是一个可怕的任务,但它似乎并不是完全无关紧要的,可能需要花费一些时间(对于其他开发人员来说可能更难以遵循)。答案 0 :(得分:1)
您的分析似乎是合理的,当您说您无法动态部署MDB以适应JCA时,您就是对的。
更多设计理念:
您可以编写一个JCA连接器,它返回SocketConnections
(本着JMS的精神),可以用来从套接字读取。要继续使用JMS类比,MDB代表MessageListener
,而您要公开的内容是MessageConsumer
。
您可以使用周期性计时器来模拟线程。而不是具有while循环的线程,您有一个重新安排自己的计时器。我使用它来为一个应用程序进行后台处理,并且工作正常。请注意,我还从EJB生成线程以在另一个应用程序中执行一些并发计算,这也很好。但是,短命的线程和bean中的业务方法会等到完全完成,所以这并不是对规范的严重违反。
另一种设计是让JCA连接器处理线程等,并将所有消息传递给MDB。 MDB将接收数据,以及关于数据对应的“信道”的信息,例如,套接字端口。这就像在一个MDB中多路复用,然后多路分解数据。您的连接器可以提供额外的API来控制线程的创建等,并且可以在EJB中注入此接口(类似于ConnectionFactory
)。您的连接器可以提供额外的API来控制线程的创建等。不是很清楚,但我希望您能理解。如果我是对的,JCA连接器可以确保将数据同步传送到MDB,至少每个插槽,以便MDB以粗略的顺序处理数据。
如果开发时间允许,我会去#3, 。
修改强>
这个选择确实部分是设计纯度的问题。使用用户spawened线程的一个问题是你显然不能为它们使用声明式事务。您可以使用UserTransaction
自己划分事务。我不知道你在这样的线程中也可以使用EntityManager
。如果您主要处理数据并且不使用中间件的许多功能,那么您可以自己创建线程。请参阅我的另一个答案:How can an EJB parallelize a long, CPU intensive process?。我想到的其他事情(不知道它们是否有问题):安全管理器可能会阻止创建线程(?),而不是创建它们,因为deamon threads可能会阻止应用程序。服务器正常关闭(?)。请注意,我在启动时从ServeletContextListener
生成了线程并且工作得很好。即使违反规范,这也是经常使用的技巧。对于“新”引入的单例bean来说,情况可能也是如此。所以,如果你的时间很短,你当然可以用一个单独的bean来尝试你的命题,看看哪些有效/无效。
答案 1 :(得分:1)
我很确定#2是最好的解决方案(也是有效的)。我没有看过新的“Singleton”ejb的规范,但我的假设是这些内部的线程是可以接受的(考虑到在这些ejbs中进行自己的同步是可以接受的)。这些设计旨在使部署管理类型服务变得更容易(以前),您可以使用JMX(尽管部署未标准化)。在JMX mbean中,您可以接受自己的线程管理,所以我会把它带到Singleton ejbs 。
快速浏览了ejb 3.1规范,我认为Singleton的唯一允许是并发控制,没有线程/套接字的东西。有点傻。我猜他们不是一个完整的JMX mbean替代品。虽然部署是非标准的,但你总是可以使用JMX mbean。如果您使用的是jboss,那么Service注释 等同于JMX mbean,其中所有内容都应该是允许的(线程,套接字等)。