Spring远程调用与JMS消息支持详解
立即解锁
发布时间: 2025-08-19 02:32:44 阅读量: 3 订阅数: 11 


Spring框架下的Java开发实践与进阶
### Spring远程调用与JMS消息支持详解
#### 1. Spring远程调用策略
Spring支持多种远程调用策略,涵盖了基于HTTP的轻量级协议(如Hessian和Burlap)、Spring自身的HTTP调用器、标准的RMI以及JAX - RPC等。这些策略为不同的远程调用场景带来了一致性和简单性,同时不牺牲功能。
##### 1.1 配置风格
Spring尽可能为所有远程调用策略提供统一的配置风格。代理可以一致地使用普通的Java业务接口,并抛出Spring的未检查异常`RemoteAccessException`。对于RMI和JAX - RPC服务,也可以选择暴露传统的RMI服务接口。此外,现有的RMI风格服务还可以通过普通Java业务接口进行代理,将每个方法调用委托给底层的RMI服务存根。
##### 1.2 服务导出机制
服务导出机制取决于实际使用的协议:
- **轻量级HTTP协议**:Hessian、Burlap和HTTP调用器允许通过为特定协议定义导出器,将现有的Spring管理的Bean作为远程服务暴露。还可以通过为同一目标Bean定义多个导出器并绑定到不同的URL,同时通过多种协议暴露同一服务实例。
- **RMI导出器**:在没有冲突的RMI基础设施的情况下,使用Spring的RMI导出器通常是无缝的。但一般不建议在运行EJB容器的进程中使用RMI导出器,因为可能会导致冲突。在J2EE Web容器(如Tomcat、Jetty或Resin)中,通过RMI导出服务效果很好,对于不在J2EE容器中运行的进程,RMI也是一个不错的选择。
- **JAX - RPC**:通过JAX - RPC导出Web服务比使用其他协议复杂得多。它涉及特定工具的特殊端点实现部署,要委托给现有的Spring管理的Bean,需要为每个服务编写一个薄的端点适配器。访问Web服务基本遵循Spring风格,但比Hessian或HTTP调用器需要更多的配置。
##### 1.3 协议选择
协议选择需要根据不同的场景进行考虑:
|场景|推荐协议|原因|
|----|----|----|
|Java到Java远程调用|Hessian、HTTP调用器或RMI调用器|避免使用跨平台协议(如SOAP),这些二进制策略更高效。Hessian允许松散耦合,后两者对对象有Java序列化的限制|
|跨平台远程调用|SOAP via JAX - RPC(特定平台)、Hessian或Burlap(有对应实现的平台)|对于支持SOAP的平台(如.NET和Delphi),SOAP是明显的选择;对于没有原生SOAP支持的平台,Hessian或Burlap是更轻量级的替代方案|
|客户端 - 服务器远程调用|基于HTTP的协议|避免防火墙问题,可通过互联网通信|
|服务器内部远程调用|RMI(非HTTP解决方案)、Hessian或HTTP调用器|Hessian和HTTP调用器在效率上大致相当|
在Spring中,协议选择在很大程度上是一个配置问题。客户端对象和服务实现都不与特定协议或远程调用API绑定,很多情况下可以在部署时切换协议。
#### 2. Spring的JMS支持
异步消息传递在许多企业应用中非常重要,Spring为消费JMS消息提供了支持,简化了编程模型,并为访问高级功能(如动态目的地)提供了一致的基础。
##### 2.1 JMS简介
JMS(Java Message Service)是一种消息传递标准,允许应用程序可靠且异步地相互通信。它支持点对点(P2P)和发布/订阅(Pub/Sub)两种消息传递类别,其异步特性使其与基于RPC的中间件技术(如RMI/IIOP)区分开来。
JMS规范有两个主要版本:JMS 1.0(包含在J2EE 1.2中)和JMS 1.1(包含在J2EE 1.4中)。JMS 1.1通过提供多态API改进了编程模型,消除了两种消息传递类别之间的功能差异。
JMS的使用不限于EJB容器,也可用于Web和独立环境。EJB容器通过消息驱动Bean(MDBs)提供创建消息消费者的基础设施,并通过支持XA的JMS提供者提供声明式和编程式事务管理。
##### 2.2 Spring支持JMS的动机
直接使用JMS API进行简单任务需要大量代码,且容易出错。以下是使用JMS 1.1 API发送文本消息的示例代码:
```java
public void testJMS() throws JMSException {
Connection connection = null;
Session session = null;
try {
connection = connectionFactory.createConnection();
session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(null);
Message message = session.createTextMessage("hello world");
producer.send(destination, message);
} finally {
if (session != null) {
try {
session.close();
} catch (JMSException ex) {
logger.warn("Failed to close the session", ex);
}
}
if (connection != null) {
try {
connection.close();
} catch (JMSException ex) {
logger.warn("Failed to close the connection", ex);
}
}
}
}
```
如果使用JMS 1.0 API,`try`块内的代码会有所不同。
##### 2.3 通过模板访问JMS
`JmsTemplate`类位于`org.springframework.jms.core`包中,实现了核心的JMS处理任务。它的设计与`JdbcTemplate`类似,提供简单的单行方法来执行常见的发送和同步接收操作,并使用回调接口处理更高级的场景。
使用`JmsTemplate`发送简单文本消息的代码如下:
```java
public void testTemplate() {
JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
jmsTemplate.convertAndSend(destination, "Hello World!");
}
```
可以看到,代码变得简单很多,无需在应用程序代码中管理资源。
`JmsTemplate`使用JMS 1.1 API,其子类`JmsTemplate102`使用JMS 1.0 API。`PubSubDomain`布尔属性用于配置`JmsTemplate`使用的消息传递类别(点对点或发布/订阅)。
`JmsTemplate`通过提供重载的`convertAndSend`和`receiveAndConvert`方法,提高了使用JMS的抽象级别,这些方法将消息数据类型表示为Java对象,通过`MessageConverter`接口进行转换。
##### 2.4 回调方法
`JmsTemplate`的许多方法使用回调接口,以提供对消息创建过程的更多控制,并向用户暴露JMS会话
0
0
复制全文
相关推荐










