JBoss EAP中MDB通过Java代码注册队列的实现方案咨询
在JBoss EAP上用Java代码动态配置MDB的队列
嘿,我来帮你搞定这个需求!你想不用注解或者ejb-jar.xml,而是通过Java代码读取配置文件来设置MDB的destination和destinationType对吧?其实有几种可行的方式,我给你拆解清楚:
方案1:注解+外部配置文件(推荐,符合Java EE规范)
Java EE本身支持在注解里用EL表达式引用外部配置,JBoss EAP也完美支持这种方式,步骤超简单:
- 先在项目的classpath下建个配置文件,比如
jms-mdb-config.properties,内容就放你要的参数:
mdb.destinationType=javax.jms.Queue mdb.destination=test_in
- 去JBoss的配置文件(比如
standalone.xml或者domain.xml)里开启属性替换,这样容器才能识别EL表达式:
<subsystem xmlns="urn:jboss:domain:ee:5.0"> <spec-descriptor-property-replacement>true</spec-descriptor-property-replacement> <jboss-descriptor-property-replacement>true</jboss-descriptor-property-replacement> <annotation-property-replacement>true</annotation-property-replacement> </subsystem>
- 然后修改你的MDB注解,用EL表达式直接引用配置里的值就行:
@MessageDriven( messageListenerInterface = MessageListener.class, activationConfig = { @ActivationConfigProperty( propertyName = "destinationType", propertyValue = "${mdb.destinationType}" ), @ActivationConfigProperty( propertyName = "destination", propertyValue = "${mdb.destination}" ) } ) public class MyTestMDB implements MessageListener { @Override public void onMessage(Message message) { // 你的消息处理逻辑 } }
部署之后,JBoss会自动把配置文件里的参数注入到MDB的激活配置里,完全不用硬编码,以后改配置直接改properties文件就行~
方案2:用JBoss专属API动态注册MDB(更灵活,但依赖容器)
如果你需要完全在Java代码里动态注册MDB(比如运行时根据不同条件切换队列),可以用JBoss的内部API,但这种方式要注意,不同版本的EAP可能API有变化,移植性差点。步骤大概是这样:
- 先读取配置文件里的参数:
Properties mdbProps = new Properties(); try (InputStream is = getClass().getClassLoader().getResourceAsStream("jms-mdb-config.properties")) { mdbProps.load(is); } catch (IOException e) { // 记得处理异常哦 e.printStackTrace(); } String destType = mdbProps.getProperty("mdb.destinationType"); String destName = mdbProps.getProperty("mdb.destination");
- 创建JBoss专属的ActivationSpec实例,把配置参数塞进去:
// 这里用的是JBoss EAP里的ActivationSpec实现,不同版本可能包名有变化 org.jboss.ejb3.mdb.inflow.JBossActivationSpec activationSpec = new org.jboss.ejb3.mdb.inflow.JBossActivationSpec(); activationSpec.setDestinationType(destType); activationSpec.setDestination(destName); // 还要设置连接工厂,一般JBoss默认的是java:/ConnectionFactory activationSpec.setConnectionFactoryLookup("java:/ConnectionFactory");
- 最后通过JBoss的部署管理器来注册MDB:
// 获取EJB容器上下文 EJBContainer ejbContainer = EJBContainer.createEJBContainer(); Context ctx = ejbContainer.getContext(); // 获取JBoss的部署管理器 DeploymentManager deploymentManager = (DeploymentManager) ctx.lookup("java:jboss/deployment-manager"); // 构建MDB的部署描述信息 MDBDeploymentDescriptor mdbDesc = new MDBDeploymentDescriptor(); mdbDesc.setMessageListenerInterface(MessageListener.class.getName()); mdbDesc.setActivationConfigProperties(activationSpec.getProperties()); // 部署这个MDB deploymentManager.deploy(mdbDesc);
这种方式适合需要动态调整的场景,但要注意和JBoss版本适配,升级EAP的时候可能要改代码。
方案3:ejb-jar.xml+外部配置(不用注解的替代方案)
如果你不想用注解,也可以在ejb-jar.xml里用EL表达式引用外部配置,和方案1原理一样:
<message-driven> <ejb-name>MyTestMDB</ejb-name> <message-listener-type>javax.jms.MessageListener</message-listener-type> <activation-config> <activation-config-property> <activation-config-property-name>destinationType</activation-config-property-name> <activation-config-property-value>${mdb.destinationType}</activation-config-property-value> </activation-config-property> <activation-config-property> <activation-config-property-name>destination</activation-config-property-name> <activation-config-property-value>${mdb.destination}</activation-config-property-value> </activation-config-property> </activation-config> </message-driven>
同样要在JBoss配置里开启属性替换,效果和方案1一样,只是把注解换成了xml配置。
总的来说,方案1是最省心的,既符合规范又不用依赖容器专属API,推荐优先用这个。如果有特殊的动态注册需求,再考虑方案2。
内容的提问来源于stack exchange,提问作者Mohit Bhagat
相关产品推荐
相关产品推荐

