简体   繁体   English

部署后立即消耗MDB中的EJB的运行时查找

[英]Run-time lookup for EJBs in MDB consuming immediately after deploy

I have Java EE 5 project using JBoss 5.1 and problem like this. 我有使用JBoss 5.1的Java EE 5项目和这样的问题。 I have to do kind of run-time lookup for some EJBs in MDBs using a string that results from message content. 我必须使用由消息内容产生的字符串对MDB中的某些EJB执行某种运行时查找。 It's just kind of service locator pattern used in MDBs. 它只是MDB中使用的一种服务定位器模式。 Now, since MDBs start consuming just after deploy, I have a lot NameNotFoundException since implicit deployment order doesn't work well here (run-time lookup). 现在,由于MDB在部署之后就开始消耗,因此我有很多NameNotFoundException因为隐式部署顺序在这里不能正常工作(运行时查找)。 What do you think about it? 你怎么看待这件事? Is it possible to do it really well using EJB 3.0? 是否有可能使用EJB 3.0做得很好? It's also acceptable for me to use any vendor-specific stuff (JBoss 5.1) if it resolves the problem. 如果解决问题,我也可以使用任何特定于供应商的东西(JBoss 5.1)。

Some code snippet to visualize the situation: 一些代码片段可视化情况:

@MessageDriven(mappedName="jms/Queue")
public class MessageBean implements MessageListener {

    @Resource
    private MessageDrivenContext mdc;

    public void onMessage(Message msg) {

        final String beanName = // extract somehow the bean's name from 'msg'
        final Context ctx = new InitialContext();
        final Object obj = ctx.lookup(beanName); // NameNotFoundException
        // do something with 'obj'
    }
}

Use one of these four different approaches. 使用这四种不同方法中的一种。

  1. Declare EJB dependencies ( EJB references ) using "@EJB" annotation (don't use JNDI lookup). 使用“@EJB”注释声明EJB依赖项( EJB引用 )(不要使用JNDI查找)。 For entity bean references, must refer to the entity bean home interface. 对于实体bean引用,必须引用实体bean home接口。 Container must ensure all dependencies are injected before methods/message-listeners are processed: 容器必须确保在处理方法/消息侦听器之前注入所有依赖项:

    MessageDriven(mappedName="jms/Queue") 消息驱动(mappedName = “JMS /队列”)
    public class MessageBean implements MessageListener { 公共类MessageBean实现MessageListener {

     @EJB private EntityBeanHomeA entityBeanHomeA; @EJB private EntityBeanHomeB entityBeanHomeB; @EJB private EntityBeanHomeC entityBeanHomeC; @EJB private SessionBeanD sessionBeanD; @Resource private MessageDrivenContext mdc; public void onMessage(Message msg) { final String beanName = // extract somehow the bean's name from 'msg' final Object obj = getDependentEJB(beanName); // do something with 'obj' } private Object getDependentEJB(String beanName) { Object result = null; if ("EntityBeanHomeA".equals(beanName)) { result = entityBeanHomeA; else if ("EntityBeanHomeB".equals(beanName)) { result = entityBeanHomeB; else ("EntityBeanHomeC".equals(beanName)) { result = entityBeanHomeC; else ("SessionBeanD".equals(beanName)) { result = sessionBeanD; } return result; } 

    } }

  2. Use JNDI lookup, but declare EJB dependencies via EJB deployment descriptors. 使用JNDI查找,但通过EJB部署描述符声明EJB依赖项。 Again, the container must ensure ensure all dependencies are setup before methods/messages are processed: 同样,容器必须确保在处理方法/消息之前确保所有依赖项都已设置:

    @MessageDriven(mappedName="jms/Queue") public class MessageBean implements MessageListener { @MessageDriven(mappedName =“jms / Queue”)公共类MessageBean实现MessageListener {

     // as given in the original Question... 

    } }

    Deployment descriptor: 部署描述符:

     <enterprise-beans> <message-driven> ... <ejb-name>MessageBean</ejb-name> <ejb-class>com.company.pkg.MessageBean</ejb-class> <messaging-type>javax.jms.MessageListener</messaging-type> <message-destination-type>javax.jms.Queue</message-destination-type> <message-destination-link>ExpenseProcessingQueue</message-destination-link> <ejb-ref> <description> This is a reference to an EJB 2.1 entity bean that encapsulates access to employee records. </description> <ejb-ref-name>ejb/EmplRecord</ejb-ref-name> <ejb-ref-type>Entity</ejb-ref-type> <home>com.wombat.empl.EmployeeRecordHome</home> <remote>com.wombat.empl.EmployeeRecord</remote> <ejb-link>EmployeeRecord</ejb-link> <-- if in same EJB jar --> <-- ../emp/emp.jar#EmployeeRecord if in diff EJB jar --> </ejb-ref> <ejb-local-ref> <description> This is a reference to the local business interface of an EJB 3.0 session bean that provides a payroll service. </description> <ejb-ref-name>ejb/Payroll</ejb-ref-name> <local>com.aardvark.payroll.Payroll</local> <ejb-link>Payroll</ejb-link> </ejb-local-ref> <ejb-local-ref> <description> This is a reference to the local business interface of an EJB 3.0 session bean that provides a pension plan service. </description> <ejb-ref-name>ejb/PensionPlan</ejb-ref-name> <local>com.wombat.empl.PensionPlan</local> <ejb-link>PensionPlan</ejb-link> <-- if in same EJB jar --> </ejb-local-ref> ... </message-driven> ... </enterprise-beans> 
  3. Use JNDI lookup but do not declare dependencies using either @EJB annotations or EJB deployment - handle entirely with your own logic, without the container helping. 使用JNDI查找,但不使用@EJB注释或EJB部署声明依赖关系 - 完全使用您自己的逻辑处理,而无需容器帮助。 Use delays/error handling. 使用延迟/错误处理。

  4. Use JBoss proprietary configuration to control deployment order: 使用JBoss专有配置来控制部署顺序:

    http://texnoblog.wordpress.com/2010/09/16/depends-in-jboss/ http://texnoblog.wordpress.com/2010/09/16/depends-in-jboss/

    How to order deployment of EJBs and JMS queue config in JBoss 5? 如何在JBoss 5中订购EJB和JMS队列配置?

One way would be to create a dummy-ejb that you inject into your MDB, this way your mdb would not start consuming until that injection can actually take place. 一种方法是创建一个你注入MDB的dummy-ejb,这样你的mdb就不会开始消耗,直到实际发生注入为止。

If the dummy-ejb is bundled with the EJBs you intended to do dynamic lookup on, this should work 如果dummy-ejb与您打算进行动态查找的EJB捆绑在一起,那么这应该可行

My answer here solves a similiar use-case. 在这里的答案解决了一个类似的用例。

I think that the best approach would be to delay the deployment of your MDB until all your EJBs are up & running. 我认为最好的方法是延迟部署MDB,直到所有EJB都启动并运行。 This is basically approach number 4 in the answer above. 这基本上是上面答案中的第4号方法。

"Use JBoss proprietary configuration to control deployment order: “使用JBoss专有配置来控制部署顺序:

http://texnoblog.wordpress.com/2010/09/16/depends-in-jboss/ http://texnoblog.wordpress.com/2010/09/16/depends-in-jboss/

How to order deployment of EJBs and JMS queue config in JBoss 5? 如何在JBoss 5中订购EJB和JMS队列配置? "

你可以在查找调用周围实现一个带退避的循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM