이 블로그 검색

2012년 7월 25일 수요일

Spring Remote (RMI) 예제


오늘 살펴볼 스프링 Remote 중에서 RMI 지원은 단순한 POJO 작성만으로도 RMI 서비스를 간편하게 발행할 수 있게 해준다. 간단한 예제를 작성해보자. 일단 프로그램은 java application 으로 하였다. RMI를 통한 통신이므로 서버 및 클라이언트 2개 프로젝트를 만들어야 한다. 먼저 서버를 만든다.

* 서버 작성 *

소스코드는 다음을 참조한다. https://github.com/jeremyko/MySpringRMI

1. Eclipse 에서 신규 프로젝트를 생성한다.

File -> New -> java project -> "MySpringRMI" 프로젝트 생성. 그리고 스프링 관련된 라이브러리들을 프로젝트 속성 -> Java Build Path -> Libraries 에 모두 추가한다.

2. 스프링 설정파일을 다음과 같이 설정한다.

// spring_conf.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"
 xmlns:p="http://www.springframework.org/schema/p"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  <bean class="org.springframework.remoting.rmi.RmiServiceExporter"
    p:service-ref="helloService"
    p:serviceName="HelloService"
    p:serviceInterface="kojh.spring.rmi.HelloService" />

  <bean id="helloService" class="kojh.spring.rmi.HelloServiceImpl"/>
</beans>

<!-- p:registryPort="1107" -->

service-ref 에는 서비스를 담당할 bean 즉, helloService로 설정한다. serviceName 속성을 통해서 RMI 서비스명을 HelloService 로 설정한다, 나중에 보게 되겠지만 이것을 참조해서 client가 이 서비스를 호출하게 된다. serviceInterface 는 해당 서비스가 구현하고 있는 인터페이스를 설정한다. 참고로, 기본적으로 RMI가 사용하는 포트는 1099 이다. 이값을 변경하기 위한 속성은 registryPort 이다.

3. 서비스 인터페이스를 정의한다.

// HelloService.java
package kojh.spring.rmi;

public interface HelloService
{
    String sayHello(String name);
}



4. 이 인터페이스를 구현하는 클래스를 정의한다.

package kojh.spring.rmi;
public class HelloServiceImpl implements HelloService
{
    public String sayHello(String name)
    {
        return "Hello " + name;
    }
}

5. 마지막으로 RMI 서비스를 발행하기 위한 Main 이 필요하다.

// DrivingMain.java
package kojh.spring.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DrivingMain
{   
    public static void main(String[] args)
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring_conf.xml");
    }
}

이것으로 RMI 서버가 완성 되었다. RMI 기능을 위한 코딩이라고 느낄만한 부분은 코드상에 어디에도 보이지 않는다는것이 Spring RMI사용의 장점이다. 모든 마법은 스프링 환경 설정 파일에서 이루어지고 있다.

* 클라이언트 작성*

소스코드는 다음을 참조한다. https://github.com/jeremyko/MySpringRMI_Client

1. Eclipse 에서 신규 프로젝트를 생성한다.

File -> New -> java project -> "MySpringRMI_Client" 프로젝트 생성. 그리고 서버 작성시와 동일하게 스프링 관련된 라이브러리들을 프로젝트 속성 -> Java Build Path -> Libraries 에 모두 추가한다.

2. 스프링 설정파일을 다음과 같이 작성한다.

 // spring_conf.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"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation=
        "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">   

  <bean id="helloServiceOfClient" class="org.springframework.remoting.rmi.RmiProxyFactoryBean"
    p:serviceUrl="rmi://localhost/HelloService"
    p:serviceInterface="kojh.rmi.interfaces.HelloService" />
   
  <context:component-scan base-package="kojh.rmi.client"/>
</beans>


serviceUrl 속성은  RMI 서비스 접근 URL 정보를 나타낸다. "rmi://" + 서버 ip + ":" + port 번호 + "/" + 서비스 명 (ex.rmi://localhost:1011/SomeService) 형식이다.

3. 서버에서 사용된 서비스의 인터페이와 동일한 인터페이스가 필요하다.

// HelloService.java
package kojh.rmi.interfaces;

public interface HelloService
{
    String sayHello(String name);
}

4. 서비스를 호출하는 작업을 담당할클래스를 정의한다.

// RmiClient.java
package kojh.rmi.client;

import kojh.rmi.interfaces.HelloService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class RmiClient
{   
    // static 이어야만 동작.
    //@Autowired: 흠..이상하게도 여기서 Autowired를 사용시에 와이어링이 되지 않는다
    private static HelloService helloServiceOfClient;

    @Autowired // 흠..여기서 Autowired 를 사용해서 Setter를 호출하게 해야 동작한다.
    public void setHelloServiceOfClient(HelloService helloService)
    {
        helloServiceOfClient = helloService;       
    }
   
    public void invokeRmi(String name)
    {
        System.out.println("invoking RMI with name ["+ name +"]");
               
        String rslt = helloServiceOfClient.sayHello(name);
       
        System.out.println("----> Result: ["+ rslt +"]");
    }
}

5. 클라이언트의 동작을 확인하기 위한 Main 클래스를 작성한다.

// RmiClientDrivingMain.java

package kojh.rmi.client;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class RMIClientDrivingMain
{
    public static void main(String[] args)
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring_conf.xml");
        RmiClient rmiClient = new RmiClient();       
        rmiClient.invokeRmi("Tom");       
        rmiClient.invokeRmi("Jane");
    }
}


구동 결과는 다음과 같다.

invoking RMI with name [Tom]
----> Result: [Hello Tom]
invoking RMI with name [Jane]
----> Result: [Hello Jane]


댓글 없음:

댓글 쓰기