不明觉厉的spring(7)---spring对远程服务的支持(对rmi和jms支持)

Spring的远程访问支持

RMI:RMI是J2SE的一部分,用来创建分布式应用。Spring对RMI的支持可以减少公开和访问RMI服务的代码量,同时还帮我们处理了RMI中的大多数繁文缛节,如RemoteException的处理等。Spring还集成了RMI和JNDI,这对于CORBA服务的公开和访问来说用处是非常大的。


JAX-RPC(web服务):即“Java API for XML-based Remote Procedure Calls”,他为访问和公开RPC风格的SOAP Web服务提供了标准的Java API。Spring提供了支持类以简化JAX-RPC客户端应用的创建和基于Servlet的服务端点的创建。就像很多Java XML API一样,JAX-RPC也拥有很多实现,其中最流行的是Apache Axis,他是完全兼容于JAX-RPC的SOAP栈。本章的JAX-RPC示例将使用Axis实现。


JAX-WS(web服务):JAX-WS 2.0是JAX-RPC的 1.1的继任者。他提供了用于公开和访问SOAP 1.2Web服务及创建客户端应用的API。本章 的JAX0WS示例将使用XFire实现。


HTTP Invoker:HTTP Invoker架构是Spring的本地远程架构,他使用标准的Java序列化和HTTP为远程组件的构建提供了简单的解决方案。HTTP Invoker使用服务器端的Servlet容器来存放远程服务。这么做的好处是可以使用HTTP认证方法增强远程服务的安全性。


Hessian:Hessian是有Caucho创建的一个二进制协议,用以简化Web服务的创建。他特定于任何特定的传输方式,但通常使用HTTP。 Spring为其提供了支持类以简化Hessian服务的创建,他使用HTTP进行传输并提供了代理支持,这样就可以透明的访问Hessian服务了。


Burlap:Burlap也是由Caucho创建的,他是一个基于XML的协议,对Hessian协议是个补充。除了协议的细节之外,Burlap的使用方式与Hessian一样。Spring对Burlap的支持与对Hessian的支持差不多,事实上,在需要交换这两个协议时,Burlap类可以轻松替换掉Hessian类。


Java消息服务(JMS):JMS API是一种消息发送标准—允许Java应用程序异步地创建、发送、接收和处理消息。它提供了松耦合的和可靠的分布式通信。默认情况下,JMS Remoting使用Java串行化,但是一个JMS提供者(例如,WebLogic JMS或JBossMQ)能够使用另外一个不同的机制(例如XStream API)以便允许通过其它技术实现消息发送。

框架

优点

缺点

RMI

全面支持Java对象串行化。因此,你能够通过网络发送复杂数据类型。

RMI仅是一种JavaJava型远程方案。如果你拥有任何非Java客户端的话,那么你无法使用它。另外,你还无法通过HTTP协议存取对象,除非你有专门的“通道”实现RMI通讯。注意,它需要一个RMI编译器(为了生成代理和框架)和一个外部注册表(用于查询服务)

Hessian/Burlap

跨防火墙工作良好

它们使用一种专利对象串行化机制。其中,Burlap仅支持Java客户端。它们能够串行化Hibernate对象,但是对集合对象执行“惰式”加载。

HTTP Invoker

基于HTTPJavaJava Remoting;通过HTTP实现Java串行化;容易建立。

服务器和客户端应用程序都需要使用Spring

仅是一种Java方案。

EJB

支持Remoting J2EE服务,应用程序安全以及事务处理

EJB是一种重量级技术。它要求使用一个J2EE容器。

Web服务

平台和语言独立

要付出SOAP操作所带来的开销,并且要求使用一个Web服务引擎。

spring对rmi的支持

自从1.1版本开始,RMI就已经成为Java的一部分,而且在很多远程方案中他都处于中心位置。Java中的CORBA支持就是通过RMI实现的,EJB也将RMI作为bean通讯的底层机制。JAX-RPC构建在RMI的概念之上以将Java对象公开成Web服务。
Java中的CORBA支持也可以通过接口定义语言(interface definition language,IDL)来实现。
IDL是一种声明性语言,可以创建彼此交互的对象---这些对象可能是不同的编程语言所创建的。
然而当前RMI在Java中使用的更广泛,这是由于其更好的安全性和垃圾收集能力。
构建RMI服务,通常你需要为服务定义一个接口,该接口继承自java.rmi.Remote接口。然后你的RMI服务需要实现该接口,最好还继承java.rmi.server.UnicastRemoteObject类。
Spring Remoting,通过RmiServiceExporter类简化上面的操作。

关于rmi原理可以参考我的另一篇博文: http://blog.csdn.net/senssic/article/details/11850131
rmi服务端
声明一个接口并实现它
package spring.senssic.rmi;


public interface Ihelloword {
	public void say();
}


package spring.senssic.rmi;


public class ImplHelloworld implements Ihelloword {


	@Override
	public void say() {
		// TODO Auto-generated method stub
		System.out.println("Hello world!");
	}


}

在spring的xml文件中配置rmi
<bean id="helloworldser" class="spring.senssic.rmi.ImplHelloworld"></bean>
<bean id="service" class="org.springframework.remoting.rmi.RmiServiceExporter">
    <!-- 服务名 -->
    <property name="serviceName" value="HelloWorldSer"></property>
    <property name="service" ref="helloworldser"></property>
    <property name="serviceInterface" value="spring.senssic.rmi.Ihelloword"></property>
       <!-- rmi registry端口号 -->
    <property name="registryPort" value="9000"></property>
       <!-- 用户通讯服务端口 -->
    <property name="servicePort" value="9001"></property>
</bean>
然后打包放入jboss或tomcat中运行web项目

这样你就可以通过服务接口与远程服务进行交互了,就好像他是本地组件一样。Spring隐藏了所有RMI细节。
就像所有的代理生成器一样,RMI代理生成器也实现了FactoryBean接口,这样我们就可以通过声明的方式创建并配置代理,然后将其做为依赖注入到组件中了。

package spring.senssic.rmi;


import spring.senssic.rmi.Ihelloword ;


public class HelloWorldClient {
	private Ihelloword helloWorldService;
	
	public void setHelloWorldService(Ihelloword helloWorldService) {
		this.helloWorldService = helloWorldService;
	}


	public void run(){
		helloWorldService.say();
	}
}

spring配置文件,客户端,用于访问rmi服务并获取代理对象

<bean id="helloWorldService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
    	<!-- 指向了RMI服务上的代理 -->
        <property name="serviceUrl" value="rmi://localhost:9000/HelloWorld" />
        <!-- 告诉代理生成器生成的接口应该实现哪个接口 -->
        <property name="serviceInterface" value="spring.senssic.rmi.Ihelloword"/>
    </bean>
    <bean id="helloWorldClient" class="spring.senssic.rmi.HelloWorldClient">
        <property name="helloWorldService" ref="helloWorldService" />
    </bean>

spring对jms的支持

关于jms可以参考我的另一篇博文: http://blog.csdn.net/senssic/article/details/11826813
Spring提供了JmsTemplate模板来简化JMS操作。利用JmsTemplate,Sender只需被注入JmsTemplate,发送的消息通过MessageCreator以回调的方式创建
发送端:
package spring.senssic.jms;

import javax.jms.JMSException;

import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

public class Sender {
	private JmsTemplate jTemplate;

	// 由sping注入
	public void setjTemplate(JmsTemplate jTemplate) {
		this.jTemplate = jTemplate;
	}

	public void send(final String text) {
		System.out.println(text);

		jTemplate.send(new MessageCreator() {

			@Override
			public javax.jms.Message createMessage(
					javax.jms.Session paramSession) throws JMSException {
				// TODO Auto-generated method stub
				return paramSession.createTextMessage(text);
			}
		});
	}
}

发送端的springxml文件配置:
<!-- jms发送 -->
<bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="QueueConnectionFactory"/><!--此处的QueueConnectionFactory为全局的jndi名称,不能随意更改由jms的各个实现厂商默认提供-->
</bean>
<bean id="jmsQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jms/queue"/>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
    <property name="defaultDestination" ref="jmsQueue"/>
</bean>
<bean id="sender" class="spring.senssic.jms.Sender">
    <property name="jTemplate" ref="jmsTemplate"/>
</bean>
发送端打包项目放到jboss或weblogic中运行发送一串字符串

然后接受端:
package spring.senssic.jms;

import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.TextMessage;

public class Revice implements MessageListener {

	@Override
	public void onMessage(Message arg0) {
		if (arg0 instanceof TextMessage) {
			TextMessage tMessage = (TextMessage) arg0;
			try {
				System.out.println("收到消息" + tMessage.getText());
			} catch (JMSException e) {
				e.printStackTrace();
			}
		}

	}

}

接受端xml配置:
<!-- jms接收 -->
<bean id="jmsConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="QueueConnectionFactory"/>
</bean>
<bean id="jmsQueue" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jms/queue"/>
</bean>

<bean id="receiver" class="spring.senssic.jms.Revice"/>
<bean id="listenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer">
    <property name="connectionFactory" ref="jmsConnectionFactory"/>
    <property name="destination" ref="jmsQueue"/>
    <property name="messageListener" ref="receiver"/>
</bean>

 自动转换消息

大多时候,除了简单的TextMessage外,需要发送消息都应当被封装在Java类中,例如,一个电子邮件消息应该通过一个MailMessage对象来表示。通常,ObjectMessage可以自动实现Java对象的序列化,不过,很多时候仍需要将消息以BytesMessage等其他形式发送,为此,Spring提供了一个MessageConverter接口来方便地实现Java类和JMS消息的转化。

public interface MessageConverter{
Object fromMessage(Message message);
Message toMessage(Object object,Session session);
}

同时,Spring内置的SimpleMessageConverter已经能够满足大多数消息的转化,它支持String和TextMessage、byte[]和ByteMessage,以及Map和MapMessage之间的转化。要在发送消息时自动将Java对象转化为消息,可以调用JmsTemplate的convertAndSend()。JmsTemplate默认使用SimpleMessageConverter作为默认的MessageConverter,要编写一个自定义的MessageConverter也是极其容易的,这里不再给出示例代码。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值