Spring JCA Message Endpoints 深度解析
概述
JCA(Java Connector Architecture,Java 连接器架构)是 Java EE 平台中定义的标准架构,用于将企业信息系统(EIS)集成到应用服务器中。Spring Framework 从 2.5 版本开始提供了对 JCA 消息端点(Message Endpoints)的支持,使得开发者可以在 Spring 应用中使用 JCA 资源适配器来接收消息,这种方式与 EJB 2.1 的消息驱动 Bean(Message-Driven Bean,MDB)非常相似。
JCA 消息端点管理提供了一种标准化的方式来处理异步消息,它利用了 JCA 资源适配器的底层消息监听机制,使得 Spring 应用能够以类似于 EJB MDB 的方式接收和处理消息,但不需要运行在完整的 EJB 容器中。
JCA 架构基础
JCA 核心概念
JCA 架构定义了以下几个核心组件:
- Resource Adapter(资源适配器):封装了与特定 EIS 系统交互的逻辑,提供了标准化的连接接口
- ActivationSpec(激活规范):定义了消息端点如何被激活和配置,包含了目标名称、消息选择器等配置信息
- MessageEndpoint(消息端点):实际处理消息的接口,实现了
javax.resource.spi.endpoint.MessageEndpoint接口 - MessageEndpointFactory(消息端点工厂):用于创建消息端点实例的工厂
JCA 与 EJB MDB 的关系
JCA 消息端点管理机制与 EJB 2.1 的消息驱动 Bean 使用相同的底层资源提供者契约。这意味着:
- 相同的资源适配器可以同时用于 EJB MDB 和 Spring 的 JCA 消息端点
- 配置方式和激活规范(ActivationSpec)的定义方式相同
- 消息处理逻辑和性能特征基本相同
Spring 框架在此基础上提供了更灵活的配置方式和更强大的依赖注入能力,使得开发者可以在轻量级的 Spring 容器中使用 JCA 消息端点,而不需要完整的 EJB 容器。
Spring JCA 消息端点支持
核心组件
Spring 提供了 JmsMessageEndpointManager 类来管理基于 JCA 的 JMS 消息端点。这个类的主要特点是:
- 自动激活规范检测:能够自动从资源适配器的类名推断出
ActivationSpec类名 - 灵活的配置方式:支持使用通用的
JmsActivationSpecConfig或特定的ActivationSpec实现 - Spring 集成:完全集成到 Spring 的 IoC 容器中,支持依赖注入和生命周期管理
JmsMessageEndpointManager
JmsMessageEndpointManager 是 Spring 提供的核心类,用于管理基于 JCA 的 JMS 消息端点。它负责:
- 创建和管理消息端点实例
- 配置激活规范(ActivationSpec)
- 管理消息端点的生命周期
- 处理资源适配器的连接和断开
配置方式
方式一:使用 JmsActivationSpecConfig(通用配置)
Spring 提供了通用的 JmsActivationSpecConfig 类,它能够自动适配不同的 JMS 提供者。这种方式适用于大多数场景,因为 Spring 会自动从资源适配器的类名推断出正确的 ActivationSpec 类。
Java 配置示例
@Configuration
public class JcaJmsConfig {
@Bean
public ResourceAdapter resourceAdapter() {
// 创建或从 JNDI 查找资源适配器
ActiveMQResourceAdapter adapter = new ActiveMQResourceAdapter();
adapter.setServerUrl("tcp://localhost:61616");
return adapter;
}
@Bean
public MessageListener orderMessageListener() {
return message -> {
try {
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
String content = textMessage.getText();
log.info("收到订单消息: {}", content);
// 处理订单逻辑
processOrder(content);
}
} catch (JMSException e) {
log.error("处理消息失败", e);
throw new RuntimeException(e);
}
};
}
@Bean
public JmsMessageEndpointManager jmsMessageEndpointManager(
ResourceAdapter resourceAdapter,
MessageListener orderMessageListener) {
// 创建激活规范配置
JmsActivationSpecConfig specConfig = new JmsActivationSpecConfig();
specConfig.setDestinationName("orderQueue");
specConfig.setDestinationType("jakarta.jms.Queue");
// 可选:设置消息选择器
specConfig.setMessageSelector("orderType = 'PREMIUM'");
// 可选:设置确认模式
specConfig.setAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
// 可选:设置并发消费者数量
specConfig.setMaxConcurrency(10);
// 创建端点管理器
JmsMessageEndpointManager endpointManager = new JmsMessageEndpointManager();
endpointManager.setResourceAdapter(resourceAdapter);
endpointManager.setActivationSpecConfig(specConfig);
endpointManager.setMessageListener(orderMessageListener);
return endpointManager;
}
}
XML 配置示例
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 资源适配器 -->
<bean id="resourceAdapter"
class="org.apache.activemq.ra.ActiveMQResourceAdapter">
<property name="serverUrl" value="tcp://localhost:61616"/>
</bean>
<!-- 消息监听器 -->
<bean id="orderMessageListener"
class="com.example.OrderMessageListener"/>
<!-- JCA 消息端点管理器 -->
<bean class="org.springframework.jms.listener.endpoint.JmsMessageEndpointManager">
<property name="resourceAdapter" ref="resourceAdapter"/>
<property name="activationSpecConfig">
<bean class="org.springframework.jms.listener.endpoint.JmsActivationSpecConfig">
<property name="destinationName" value="orderQueue"/>
<property name="destinationType" value="jakarta.jms.Queue"/>
<property name="messageSelector" value="orderType = 'PREMIUM'"/>
<property name="acknowledgeMode" value="1"/> <!-- AUTO_ACKNOWLEDGE -->
<property name="maxConcurrency" value="10"/>
</bean>
</property>
<property name="messageListener" ref="orderMessageListener"/>
</bean>
</beans>
方式二:使用特定的 ActivationSpec(精确控制)
如果需要对激活规范进行更精确的控制,或者资源适配器不支持自动检测,可以直接使用特定的 ActivationSpec 实现类。
ActiveMQ 示例
@Configuration
public class ActiveMQJcaConfig {
@Bean
public ResourceAdapter resourceAdapter() {
ActiveMQResourceAdapter adapter = new ActiveMQResourceAdapter();
adapter.setServerUrl("tcp://localhost:61616");
return adapter;
}
@Bean
public MessageListener orderMessageListener() {
return message -> {
// 消息处理逻辑
processMessage(message);
};
}
@Bean
public JmsMessageEndpointManager jmsMessageEndpointManager(
ResourceAdapter resourceAdapter,
MessageListener orderMessageListener) {
// 创建 ActiveMQ 特定的激活规范
ActiveMQActivationSpec spec = new ActiveMQActivationSpec();
spec.setDestination("orderQueue");
spec.setDestinationType("jakarta.jms.Queue");
spec.setSubscriptionDurability("NonDurable");
spec.setMessageSelector("orderType = 'PREMIUM'");
// 创建端点管理器
JmsMessageEndpointManager endpointManager = new JmsMessageEndpointManager();
endpointManager.setResourceAdapter(resourceAdapter);
endpointManager.setActivationSpec(spec);
endpointManager.setMessageListener(orderMessageListener);
return endpointManager;
}
}
从 JNDI 查找 ActivationSpec
在某些企业环境中,激活规范可能已经配置在应用服务器中,可以通过 JNDI 查找:
@Configuration
public class JndiJcaConfig {
@Bean
public JndiTemplate jndiTemplate() {
JndiTemplate template = new JndiTemplate();
Properties properties = new Properties();
properties.put("java.naming.factory.initial",
"org.apache.activemq.jndi.ActiveMQInitialContextFactory");
properties.put("java.naming.provider.url", "tcp://localhost:61616");
template.setEnvironment(properties);
return template;
}
@Bean
public ActivationSpec activationSpec(JndiTemplate jndiTemplate) throws NamingException {
return (ActivationSpec) jndiTemplate.lookup("java:comp/env/jms/OrderActivationSpec");
}
@Bean
public ResourceAdapter resourceAdapter(JndiTemplate jndiTemplate) throws NamingException {
return (ResourceAdapter) jndiTemplate.lookup("java:comp/env/jms/OrderResourceAdapter");
}
@Bean
public JmsMessageEndpointManager jmsMessageEndpointManager(
ResourceAdapter resourceAdapter,
ActivationSpec activationSpec,
MessageListener orderMessageListener) {
JmsMessageEndpointManager endpointManager = new JmsMessageEndpointManager();
endpointManager.setResourceAdapter(resourceAdapter);
endpointManager.setActivationSpec(activationSpec);
endpointManager.setMessageListener(orderMessageListener);
return endpointManager;
}
}
XML 配置中使用 JNDI 查找
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee.xsd">
<!-- 从 JNDI 查找激活规范 -->
<jee:jndi-lookup id="activationSpec"
jndi-name="java:comp/env/jms/OrderActivationSpec"/>
<!-- 从 JNDI 查找资源适配器 -->
<jee:jndi-lookup id="resourceAdapter"
jndi-name="java:comp/env/jms/OrderResourceAdapter"/>
<!-- 消息监听器 -->
<bean id="orderMessageListener"
class="com.example.OrderMessageListener"/>
<!-- JCA 消息端点管理器 -->
<bean class="org.springframework.jms.listener.endpoint.JmsMessageEndpointManager">
<property name="resourceAdapter" ref="resourceAdapter"/>
<property name="activationSpec" ref="activationSpec"/>
<property name="messageListener" ref="orderMessageListener"/>
</bean>
</beans>
JmsActivationSpecConfig 配置选项
JmsActivationSpecConfig 提供了丰富的配置选项,用于定制消息端点的行为:
基本配置
JmsActivationSpecConfig specConfig = new JmsActivationSpecConfig();
// 目标名称(队列或主题名称)
specConfig.setDestinationName("orderQueue");
// 目标类型:jakarta.jms.Queue 或 jakarta.jms.Topic
specConfig.setDestinationType("jakarta.jms.Queue");
// 消息选择器(SQL-92 风格的表达式)
specConfig.setMessageSelector("orderType = 'PREMIUM' AND priority > 5");
确认模式配置
// 自动确认(默认)
specConfig.setAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
// 客户端确认
specConfig.setAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
// 事务模式
specConfig.setAcknowledgeMode(Session.SESSION_TRANSACTED);
// 重复确认模式
specConfig.setAcknowledgeMode(Session.DUPS_OK_ACKNOWLEDGE);
并发和性能配置
// 最大并发消费者数量
specConfig.setMaxConcurrency(10);
// 最小并发消费者数量
specConfig.setMinConcurrency(1);
// 预取消息数量
specConfig.setMaxMessagesPerSession(10);
订阅配置(仅适用于主题)
// 订阅名称(用于持久订阅)
specConfig.setSubscriptionName("orderSubscription");
// 订阅是否持久化
specConfig.setSubscriptionDurability(true);
// 客户端 ID(用于持久订阅)
specConfig.setClientId("orderClient");
高级配置
// 接收超时时间(毫秒)
specConfig.setReceiveTimeout(1000);
// 是否启用本地事务
specConfig.setTransactionManager(transactionManager);
// 自定义激活规范属性
Properties properties = new Properties();
properties.setProperty("customProperty", "customValue");
specConfig.setActivationSpecProperties(properties);
完整的实战示例
示例:订单处理系统
以下是一个完整的订单处理系统示例,展示了如何使用 JCA 消息端点:
// 订单实体
public class Order {
private String orderId;
private String orderType;
private BigDecimal amount;
private LocalDateTime orderTime;
// getters and setters
}
// 订单消息监听器
@Component
public class OrderMessageListener implements MessageListener {
private static final Logger log = LoggerFactory.getLogger(OrderMessageListener.class);
@Autowired
private OrderService orderService;
@Autowired
private JmsTemplate jmsTemplate;
@Override
public void onMessage(Message message) {
try {
if (message instanceof TextMessage) {
TextMessage textMessage = (TextMessage) message;
String jsonContent = textMessage.getText();
// 解析订单
ObjectMapper mapper = new ObjectMapper();
Order order = mapper.readValue(jsonContent, Order.class);
log.info("收到订单消息: {}", order.getOrderId());
// 处理订单
orderService.processOrder(order);
// 如果需要,发送确认消息
sendConfirmation(order);
} else if (message instanceof ObjectMessage) {
ObjectMessage objectMessage = (ObjectMessage) message;
Order order = (Order) objectMessage.getObject();
log.info("收到订单对象消息: {}", order.getOrderId());
orderService.processOrder(order);
} else {
log.warn("收到未知类型的消息: {}", message.getClass().getName());
}
} catch (Exception e) {
log.error("处理订单消息失败", e);
// 发送到死信队列
sendToDeadLetterQueue(message, e);
}
}
private void sendConfirmation(Order order) {
// 发送确认消息的逻辑
}
private void sendToDeadLetterQueue(Message message, Exception error) {
// 发送到死信队列的逻辑
}
}
// 订单服务
@Service
public class OrderService {
public void processOrder(Order order) {
// 订单处理逻辑
validateOrder(order);
saveOrder(order);
notifyInventory(order);
}
private void validateOrder(Order order) {
// 订单验证逻辑
}
private void saveOrder(Order order) {
// 保存订单逻辑
}
private void notifyInventory(Order order) {
// 通知库存系统逻辑
}
}
// JCA 配置
@Configuration
public class OrderJcaConfig {
@Bean
public ResourceAdapter resourceAdapter() {
ActiveMQResourceAdapter adapter = new ActiveMQResourceAdapter();
adapter.setServerUrl("tcp://localhost:61616");
adapter.setUserName("admin");
adapter.setPassword("admin");
return adapter;
}
@Bean
public JmsMessageEndpointManager orderMessageEndpointManager(
ResourceAdapter resourceAdapter,
OrderMessageListener orderMessageListener) {
JmsActivationSpecConfig specConfig = new JmsActivationSpecConfig();
// 配置目标队列
specConfig.setDestinationName("orderQueue");
specConfig.setDestinationType("jakarta.jms.Queue");
// 配置消息选择器:只处理高级订单
specConfig.setMessageSelector("orderType = 'PREMIUM'");
// 配置确认模式
specConfig.setAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
// 配置并发
specConfig.setMaxConcurrency(5);
specConfig.setMinConcurrency(2);
// 创建端点管理器
JmsMessageEndpointManager endpointManager = new JmsMessageEndpointManager();
endpointManager.setResourceAdapter(resourceAdapter);
endpointManager.setActivationSpecConfig(specConfig);
endpointManager.setMessageListener(orderMessageListener);
return endpointManager;
}
// 配置多个端点管理器处理不同类型的订单
@Bean
public JmsMessageEndpointManager standardOrderMessageEndpointManager(
ResourceAdapter resourceAdapter,
OrderMessageListener orderMessageListener) {
JmsActivationSpecConfig specConfig = new JmsActivationSpecConfig();
specConfig.setDestinationName("orderQueue");
specConfig.setDestinationType("jakarta.jms.Queue");
specConfig.setMessageSelector("orderType = 'STANDARD'");
specConfig.setAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
specConfig.setMaxConcurrency(10);
JmsMessageEndpointManager endpointManager = new JmsMessageEndpointManager();
endpointManager.setResourceAdapter(resourceAdapter);
endpointManager.setActivationSpecConfig(specConfig);
endpointManager.setMessageListener(orderMessageListener);
return endpointManager;
}
}
通用消息端点管理器
除了专门针对 JMS 的 JmsMessageEndpointManager,Spring 还提供了通用的 GenericMessageEndpointManager,它可以用于任何类型的消息监听器,而不仅仅是 JMS。
GenericMessageEndpointManager 使用示例
@Configuration
public class GenericJcaConfig {
@Bean
public ResourceAdapter resourceAdapter() {
// 任何类型的资源适配器
return new CustomResourceAdapter();
}
@Bean
public MessageListener customMessageListener() {
// 任何实现了 MessageListener 接口的监听器
return new CustomMessageListener();
}
@Bean
public GenericMessageEndpointManager genericMessageEndpointManager(
ResourceAdapter resourceAdapter,
MessageListener customMessageListener) {
// 创建自定义的激活规范
CustomActivationSpec spec = new CustomActivationSpec();
spec.setDestination("customDestination");
spec.setCustomProperty("customValue");
// 创建通用端点管理器
GenericMessageEndpointManager endpointManager = new GenericMessageEndpointManager();
endpointManager.setResourceAdapter(resourceAdapter);
endpointManager.setActivationSpec(spec);
endpointManager.setMessageListener(customMessageListener);
return endpointManager;
}
}
生命周期管理
JmsMessageEndpointManager 实现了 Spring 的 Lifecycle 接口,可以自动管理消息端点的启动和停止:
@Configuration
public class LifecycleJcaConfig {
@Bean
public JmsMessageEndpointManager jmsMessageEndpointManager(
ResourceAdapter resourceAdapter,
MessageListener messageListener) {
JmsActivationSpecConfig specConfig = new JmsActivationSpecConfig();
specConfig.setDestinationName("orderQueue");
JmsMessageEndpointManager endpointManager = new JmsMessageEndpointManager();
endpointManager.setResourceAdapter(resourceAdapter);
endpointManager.setActivationSpecConfig(specConfig);
endpointManager.setMessageListener(messageListener);
// 自动启动(默认)
endpointManager.setAutoStartup(true);
return endpointManager;
}
}
// 手动控制生命周期
@Service
public class MessageEndpointLifecycleService {
@Autowired
private JmsMessageEndpointManager endpointManager;
public void startEndpoint() {
if (!endpointManager.isRunning()) {
endpointManager.start();
log.info("消息端点已启动");
}
}
public void stopEndpoint() {
if (endpointManager.isRunning()) {
endpointManager.stop();
log.info("消息端点已停止");
}
}
public boolean isEndpointRunning() {
return endpointManager.isRunning();
}
}
JCA 消息端点 vs 传统消息监听器
对比分析
| 特性 | JCA 消息端点 | 传统消息监听器(DefaultMessageListenerContainer) |
|---|---|---|
| 架构基础 | 基于 JCA 标准 | 基于 JMS API |
| 容器依赖 | 需要资源适配器 | 只需要连接工厂 |
| 部署方式 | 可以部署到应用服务器 | 独立运行 |
| 配置复杂度 | 相对复杂 | 相对简单 |
| 标准化程度 | 高度标准化 | 框架特定 |
| 企业集成 | 更适合企业级集成 | 更适合独立应用 |
| 性能 | 取决于资源适配器实现 | 取决于容器实现 |
选择建议
使用 JCA 消息端点的情况:
- 需要与已有的 EJB MDB 共享相同的资源适配器
- 部署在应用服务器环境中,资源适配器已经配置好
- 需要利用应用服务器的连接池和资源管理
- 需要与其他的 JCA 资源(如数据库连接)在同一事务中
使用传统消息监听器的情况:
- 独立应用或 Spring Boot 应用
- 需要更灵活的配置和更简单的部署
- 不需要应用服务器的资源管理
- 需要快速开发和测试
最佳实践
1. 资源适配器配置
@Configuration
public class ResourceAdapterBestPractices {
@Bean
public ResourceAdapter resourceAdapter() {
ActiveMQResourceAdapter adapter = new ActiveMQResourceAdapter();
// 配置连接池
adapter.setServerUrl("tcp://localhost:61616");
adapter.setUserName("admin");
adapter.setPassword("admin");
// 启用连接池
adapter.setUseJndi(false);
return adapter;
}
// 使用 ResourceAdapterFactoryBean 进行更高级的配置
@Bean
public ResourceAdapterFactoryBean resourceAdapterFactoryBean() {
ResourceAdapterFactoryBean factoryBean = new ResourceAdapterFactoryBean();
factoryBean.setResourceAdapter(new ActiveMQResourceAdapter());
// 配置工作管理器
factoryBean.setWorkManager(workManager());
// 配置事务管理器
factoryBean.setTransactionManager(transactionManager());
return factoryBean;
}
}
2. 错误处理
@Component
public class RobustOrderMessageListener implements MessageListener {
private static final Logger log = LoggerFactory.getLogger(RobustOrderMessageListener.class);
@Autowired
private JmsTemplate jmsTemplate;
@Autowired
private DeadLetterQueueService deadLetterQueueService;
@Override
public void onMessage(Message message) {
try {
processMessage(message);
} catch (BusinessException e) {
// 业务异常:记录日志,可能需要重试
log.error("业务处理失败: {}", e.getMessage(), e);
handleBusinessException(message, e);
} catch (TransientException e) {
// 临时异常:可以重试
log.warn("临时异常,将重试: {}", e.getMessage());
retryMessage(message);
} catch (Exception e) {
// 系统异常:发送到死信队列
log.error("系统异常,发送到死信队列", e);
deadLetterQueueService.sendToDeadLetterQueue(message, e);
}
}
private void processMessage(Message message) throws Exception {
// 消息处理逻辑
}
private void handleBusinessException(Message message, BusinessException e) {
// 业务异常处理逻辑
}
private void retryMessage(Message message) {
// 重试逻辑
}
}
3. 性能优化
@Configuration
public class PerformanceOptimizedJcaConfig {
@Bean
public JmsMessageEndpointManager optimizedMessageEndpointManager(
ResourceAdapter resourceAdapter,
MessageListener messageListener) {
JmsActivationSpecConfig specConfig = new JmsActivationSpecConfig();
specConfig.setDestinationName("orderQueue");
// 优化并发配置
specConfig.setMaxConcurrency(20); // 最大并发数
specConfig.setMinConcurrency(5); // 最小并发数
// 优化消息预取
specConfig.setMaxMessagesPerSession(50);
// 使用客户端确认以获得更好的控制
specConfig.setAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE);
JmsMessageEndpointManager endpointManager = new JmsMessageEndpointManager();
endpointManager.setResourceAdapter(resourceAdapter);
endpointManager.setActivationSpecConfig(specConfig);
endpointManager.setMessageListener(messageListener);
return endpointManager;
}
}
4. 事务集成
@Configuration
@EnableTransactionManagement
public class TransactionalJcaConfig {
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public JmsTransactionManager jmsTransactionManager(ConnectionFactory connectionFactory) {
return new JmsTransactionManager(connectionFactory);
}
@Bean
public ChainedTransactionManager chainedTransactionManager(
PlatformTransactionManager dataSourceTransactionManager,
JmsTransactionManager jmsTransactionManager) {
return new ChainedTransactionManager(
dataSourceTransactionManager,
jmsTransactionManager
);
}
@Service
public class TransactionalOrderService {
@Autowired
private OrderRepository orderRepository;
@Autowired
private JmsTemplate jmsTemplate;
@Transactional(transactionManager = "chainedTransactionManager")
public void processOrderTransactionally(Order order) {
// 保存订单到数据库
orderRepository.save(order);
// 发送确认消息
jmsTemplate.convertAndSend("order.confirmation", order);
// 如果任何操作失败,整个事务都会回滚
}
}
}
总结
Spring Framework 对 JCA 消息端点的支持为开发者提供了一种标准化、企业级的方式来处理异步消息。主要优势包括:
- 标准化架构:基于 JCA 标准,与 EJB MDB 使用相同的底层机制
- 企业级集成:可以充分利用应用服务器的资源管理和连接池
- 灵活配置:支持通用配置和特定实现配置两种方式
- Spring 集成:完全集成到 Spring IoC 容器,支持依赖注入和生命周期管理
- 事务支持:可以与 Spring 事务管理无缝集成
虽然 JCA 消息端点主要适用于企业级应用服务器环境,但 Spring 的抽象层使得配置和使用变得相对简单。对于独立应用或 Spring Boot 应用,传统的消息监听器容器可能更加合适;但对于需要与现有 EJB 应用共享资源或部署在应用服务器中的场景,JCA 消息端点提供了标准化的解决方案。