Sie sind auf Seite 1von 45

copyright 2009 Trainologic LTD

Abstracting the Protocols


Spring Remoting
copyright 2009 Trainologic LTD
Spring Remoting
Introduction
Remoting by RMI
Remoting by Hessian or Burlap
Remoting by HTTP Invokers
Web Services
Remoting by JMS
Introduction
3
copyright 2009 Trainologic LTD
Spring Remoting

Remoting is an application feature by which an object is


exposed for remote invocations.

As we are going to see, Spring supports several


remoting protocols (e.g., RMI, JMS).

Remoting is easily done with Spring; it usually requires


changes only in the xml configuration file.
Remoting
3
4
copyright 2009 Trainologic LTD
Spring Remoting

Without Spring, the remoting logic is mixed with the


business logic.

For example, when using RMI, the remote object needs


to implement the Remote interface.

It also needs to be exposed by using the


UnicastRemoteObject.

The same goes for the other protocols.


Remoting without Spring
4
5
copyright 2009 Trainologic LTD
Spring Remoting

Using the Spring framework for remoting introduces the


following benefits:

Protocol associated code doesnt appear in the source


code.

The wiring logic appears solely in the XML


configuration files.

It is possible to switch between different remoting


protocols without changing the source code!
Using Springs Remoting
5
copyright 2009 Trainologic LTD
Spring Remoting
Introduction
Remoting by RMI
Remoting by Hessian or Burlap
Remoting by HTTP Invokers
Web Services
Remoting by JMS
Remoting by RMI
77
copyright 2008 trainologic LTD
Spring Remoting

RMI stands for: Remote Method Invocation.

RMI is used for making invocations on a remote object.

A remote object is an object which resides on a different


JVM than the calling object.

Hence, we cant have a direct reference to this object.


RMI Recap
7
77
copyright 2008 trainologic LTD
Spring Remoting

Making remote invocations is not a simple task.

You have to manage socket connections, serialization of


method parameters, deserialization and the same for the
returned value.

Moreover, an object sent as a parameter may be a large


object graph.

RMI eliminates the need to handle serialization &


networking for remote invocations.
Motivation for RMI
8
77
copyright 2008 trainologic LTD
Spring Remoting

The RMI architecture:


Diagram
9
Client Server
Interface Interface
Remote Object
S
k
e
l
e
t
o
n
S
t
u
b
77
copyright 2008 trainologic LTD
Spring Remoting

As you can see, two classes implement the business


interface:

The remote object implementation (the business


object).

The stub.

What is this stub anyway?


Discussion
10
77
copyright 2008 trainologic LTD
Spring Remoting

The Stub represents the remote object on the client


machine.

The stub is responsible for the network transportation of


the invocation.

From the clients point-of-view, it invokes a local


method.

The Stub communicates with the skeleton which is a


server-side proxy responsible for network management
& serialization at the server side.

They are automatically generated.


Stubs & Skeletons
11
77
copyright 2008 trainologic LTD
Spring Remoting

How can the client get hold of the Stub?

By the use of rmiregistry.

The server should bind the remote object to the


rmiregistry under a specific name.

Then, the client will lookup the object by the name.

Lets see how it works


The Registry
12
77
copyright 2008 trainologic LTD
Spring Remoting
The Server Side (without Spring)
13
// This is the remote object's interface
public interface Greeter extends Remote {
// / all methods must declared throwing RemoteException
String greet(User user) throws RemoteException;
}
// Extending the UnicastRemoteObject for network handling
public class GreeterImpl extends UnicastRemoteObject implements
Greeter {
// Must explicitly declare the constructor because of exception
// handling.
protected GreeterImpl() throws RemoteException {
super();
}
public String greet(User user) {
return "Hello " + user.getName();
}
}
77
copyright 2008 trainologic LTD
Spring Remoting
The Server Side (without Spring)
14
// Must be Serializable
public class User implements Serializable {
private String name;
private int age;
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public int getAge() {return age;}
public void setAge(int age) {this.age = age;}
}
public static void main(String[] args) throws Exception {
Greeter greet = new GreeterImpl();
Naming.bind("greeter", greet);
}
77
copyright 2008 trainologic LTD
Spring Remoting

As you can see, RMI has some rules:

The remote interface must extend java.rmi.Remote.

All remote interface methods must declare throwing


RemoteException.

The parameter classes must be Serializable.

The implementation class must either extend


UnicastRemoteObject (as shown) or, when creating
the object, the static method exportObject() should
be invoked.
Discussion
15
77
copyright 2008 trainologic LTD
Spring Remoting
The Client Side (without Spring)
16
public static void main(String[] args) throws Exception {
Greeter greeter = (Greeter) Naming.lookup("greeter");
User user = new User();
user.setAge(31);
user.setName("Shimi");
System.out.println(greeter.greet(user));
}

The client is very simple:


17
copyright 2009 Trainologic LTD
Spring Remoting

Spring allows you to expose a POJO by RMI.

This is done only in the xml configuration file.

Spring provides the RmiServiceExporter class which


exports the POJO over RMI.

Lets see an example


RMI with Spring
17
18
copyright 2009 Trainologic LTD
Spring Remoting

We are going to expose the following POJO:


The Remote Object
18
public interface Crier {
String cry();
}
public class CrierImpl implements Crier {
private String cry;
public void setCry(String cry) {
this.cry = cry;
}
@Override
public String cry() {
return cry;
}
}
19
copyright 2009 Trainologic LTD
Spring Remoting
The Configuration File
19
<beans >
<bean name="crier"
class="com.trainologic.examples.spring.remoting.CrierImpl">
<property name="cry" value="Wolf Wolf" />
</bean>
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="serviceName" value="CrierService" />
<property name="service" ref="crier" />
<property name="serviceInterface"
value="com.trainologic.examples.spring.remoting.Crier" />
<property name="registryPort" value="1199" />
</bean>
</beans>
20
copyright 2009 Trainologic LTD
Spring Remoting

The RmiServiceExporter has the following configuration


properties:

serviceName the name of the remote object by


which the binding in the rmiregistry will be done.

service a reference to the Spring bean that is to be


exported.

serviceInterface specifies which interface to


expose.

registryPort the port on which the rmiregistry


listens.
RmiServiceExporter
20
21
copyright 2009 Trainologic LTD
Spring Remoting

Wait a sec.

Do I need to start a rmiregisty in order for the example


to work?

Well, no!

If Spring doesnt find a rmiregistry it will create a new


one (you will see it in the log).

The default rmiregistry port is: 1099.


The rmiregistry
21
22
copyright 2009 Trainologic LTD
Spring Remoting

We finished writing the server.

When the ApplicationContext is created, the POJO will be


available by RMI.

RMI clients can now safely work with the object.

However, if you are using Spring on the client side, it


becomes very easy to consume the service.

Lets see how its done


The Client
22
23
copyright 2009 Trainologic LTD
Spring Remoting
The Client Configuration File
23
<beans >
<bean id="crierService"
class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl"
value="rmi://localhost:1199/CrierService" />
<property name="serviceInterface"
value="com.trainologic.examples.spring.remoting.Crier" />
</bean>
</beans>
24
copyright 2009 Trainologic LTD
Spring Remoting

The client code is simplicity itself:


The Client Code
24
public static void main(String[] args) {
BeanFactory factory = new FileSystemXmlApplicationContext(
"applicationContext.xml");
Crier c = (Crier) factory.getBean("crierService");
System.out.println(c.cry());
}
copyright 2009 Trainologic LTD
Spring Remoting
Introduction
Remoting by RMI
Remoting by Hessian or Burlap
Remoting by HTTP Invokers
Web Services
Remoting by JMS
Remoting by Hessian or Burlap
26
copyright 2009 Trainologic LTD
Spring Remoting

Hessian is a binary web services protocol.

It was developed by Caucho.

The Hessian protocol is very compact and simple. Its


well suited for applications that need high performance.

Burlap is the XML equivalent for the Hessian protocol.

Burlap is a simple subset of XML and its main purpose is


to allow EJBs to interoperable with non-Java servers.
The Hessian & Burlap Protocols
26
27
copyright 2009 Trainologic LTD
Spring Remoting

Because they work on HTTP, both Hessian and Burlap


require a Servlet container.

For exporting beans over the Hessian or Burlap


protocols, you need to use Spring MVC
DispatcherServlet (covered in the Spring MVC chapter).

Lets see an example of this definition in the web.xml


The Hessian & Burlap Protocols
27
28
copyright 2009 Trainologic LTD
Spring Remoting
Configuring the DispatcherServlet
28
<web-app ...>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/remoting/*</url-pattern>
</servlet-mapping>
</web-app>
29
copyright 2009 Trainologic LTD
Spring Remoting

In this example, the application context file will be


named: dispatcher-servlet.xml.

Now, we can export a bean in this file over the Hessian/


Burlap protocols.

Lets see an example of exporting a bean over both


protocols
Exporting our Beans
29
30
copyright 2009 Trainologic LTD
Spring Remoting
dispatcher-servlet.xml
30
<?xml version="1.0" encoding="UTF-8"?>
<beans >
<bean name="echo" class="com.trainologic...EchoImpl" />
<bean name="/remoting/samplehessian.do"
class="org.springframework.remoting.caucho.HessianServiceExporter">
<property name="service" ref="echo" />
<property name="serviceInterface" value="com.trainologicEcho" />
</bean>
<bean name="/remoting/sampleburlap.do"
class="org.springframework.remoting.caucho.BurlapServiceExporter">
<property name="service" ref="echo" />
<property name="serviceInterface" value="com.trainologicEcho" />
</bean>
</beans>
31
copyright 2009 Trainologic LTD
Spring Remoting

The same as with RMI, we use Springs proxy factory


beans to connect to Hessian/Burlap services:
Client Side
31
<bean id="echoService1"
class="org.springframework.remoting.caucho.HessianProxyFactoryBean">
<property name="serviceUrl"
value="http://remotehost:8080/remoting/samplehessian.do" />
<property name="serviceInterface" value="...Echo" />
</bean>
<bean id="echoService2"
class="org.springframework.remoting.caucho.BurlapProxyFactoryBean">
<property name="serviceUrl"
value="http://remotehost:8080/remoting/sampleburlap.do" />
<property name="serviceInterface" value="...Echo" />
</bean>
copyright 2009 Trainologic LTD
Spring Remoting
Introduction
Remoting by RMI
Remoting by Hessian or Burlap
Remoting by HTTP Invokers
Web Services
Remoting by JMS
Remoting by HTTP Invokers
33
copyright 2009 Trainologic LTD
Spring Remoting

Hessian and Burlap are lightweight protocols.

They do not support serialization of complex object


graphs.

Springs HTTP Invokers rely on the standard Java


serialization and provides the serialization over HTTP.

Exposing the service and connecting from the client is


very similar to the previously shown protocols
HTTP Invokers
33
34
copyright 2009 Trainologic LTD
Spring Remoting
Example
34
<bean name="/remoting/samplehttpinvoker.do class="org
remoting.httpinvoker.HttpInvokerServiceExporter">
<property name="service" ref="echo" />
<property name="serviceInterface" value="com.trainologicEcho" />
</bean>

Server side:

Client side:
<bean id="echoService3"
class="orgremoting.httpinvoker.HttpInvokerProxyFactoryBean">
<property name="serviceUrl"
value="http://remotehost:8080/remoting/samplehttpinvoker.do" />
<property name="serviceInterface" value="...Echo" />
</bean>
35
copyright 2009 Trainologic LTD
Spring Remoting

Note that Http Invokers mandate not only a Java-to-Java


architecture, but also Spring on both sides.

Note that there are known issues in using Hessian/


Burlap with Hibernate objects that contain lazy-
initialized collections. Prefer Http Invokers in these
cases.
Discussion
35
copyright 2009 Trainologic LTD
Spring Remoting
Introduction
Remoting by RMI
Remoting by Hessian or Burlap
Remoting by HTTP Invokers
Web Services
Remoting by JMS
Web Services
37
copyright 2009 Trainologic LTD
Spring Remoting

Spring supports both JAX-RPC and JAX-WS standards.

JAX-RPC is the old Java standard which focuses on the


RPC aspect of web services.

In JavaEE 5 and JavaSE 6 it was replaced by JAX-WS.

We will focus on JAX-WS in this section.

For more information about Springs integration with


JAX-RPC, please consult the documentation.
Web Service & Spring
37
38
copyright 2009 Trainologic LTD
Spring Remoting

In order to export your bean as a JAX-WS Web Service,


you need to provide a dedicated endpoint class.

Lets see it by an example.

Were going to export the following class as a Web


Service:
Exporting a Service
38
public class EchoImpl implements Echo {
public String echo(String msg) {
System.out.println(msg);
return msg;

}
39
copyright 2009 Trainologic LTD
Spring Remoting
The Endpoint Class
39
@WebService(serviceName = "echoService")
public class WSSample extends SpringBeanAutowiringSupport {
@Autowired
private Echo echoImpl;
@WebMethod
public String echo(String msg) {
return echoImpl.echo(msg);
}
}

Spring provides a convenience utility class for providing


autowiring for your endpoint classes:
40
copyright 2009 Trainologic LTD
Spring Remoting

All that is left to do now is to start the Web Service.

Note that Spring doesnt come with its own JAX-WS


implementation.

So, whether you use JAX-WS RI, AXIS2, Apache CXF,


etc., you must consult the documentation regarding how
to start the Web Service.

It is important to remember that the JAX-WS framework


will manage the life-cycle of the Web Service.

Spring will provide the dependencies.


Exposing the Service
40
41
copyright 2009 Trainologic LTD
Spring Remoting

Like before, accessing a Web Service is done by a


dedicated ProxyFactorybean.

Example:
Accessing a Web Service
41
<bean id="echoService4"
class="orgremoting.jaxws.JaxWsPortProxyFactoryBean ">
<property name=wsdlDocumentUrl"
value="http://remotehost:8080/remoting/samplews?wsdl" />
<property name="serviceInterface" value="...Echo" />
<property name=namespaceURI"
value=http://www.trainologic.com/examples/ws" />
<property name="serviceName" value=EchoService" />
<property name=portName" value=EchoPort" />
</bean>
copyright 2009 Trainologic LTD
Spring Remoting
Introduction
Remoting by RMI
Remoting by Hessian or Burlap
Remoting by HTTP Invokers
Web Services
Remoting by JMS Remoting by JMS
43
copyright 2009 Trainologic LTD
Spring Remoting

Springs support for JMS is discussed in a separate


chapter.

Here well focus on JMS remoting.

The main advantages of using JMS for remoting is the


clustering support and load-balancing that is native to
the messaging software.

Note that Springs support is pretty basic and sending


and receiving is done on the same thread in the same
non-transactioned session.
JMS Remoting
43
44
copyright 2009 Trainologic LTD
Spring Remoting
Server Side Configuration
44
<!-- exporting the bean through JMS protocol -->
<bean id="sampleJMSService"
class="org.springframework.jms.remoting.JmsInvokerServiceExporter">
<property name="serviceInterface" value="...Echo" />
<property name="service">
<bean class="...EchoImpl" />
</property>
</bean>
<!--
creating the JMS listener container (elaborated in the JMS chapter)
-->
<bean class="orgjms.listener.SimpleMessageListenerContainer">
<property name="connectionFactory" ref="connectionFactory" />
<property name="destination" ref="queue" />
<property name="concurrentConsumers" value="3" />
<property name="messageListener" ref="sampleJMSService" />
</bean>
45
copyright 2009 Trainologic LTD
Spring Remoting
Client Side Configuration
45
<bean id=sampleJMSService"
class="orgjms.remoting.JmsInvokerProxyFactoryBean">
<property name="serviceInterface" value=Echo" />
<property name="connectionFactory" ref="connectionFactory" />
<property name="queue" ref="queue" />
</bean>

Das könnte Ihnen auch gefallen