Spring RMI를
사용해보기
위해
간단한
클래스들을
작성해
보았다..
일단, 서비스를
제공하는
측의 Service 클래스를
만들어보자..
RMISearchService.java
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public interface RMISearchService {
Log logger = LogFactory.getLog(RMISearchService.class);
String search(String keyword);
}
RMISearchServiceImpl.java
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class RMISearchServiceImpl implements RMISearchService {
Log logger = LogFactory.getLog(RMISearchServiceImpl.class);
@Override
public String search(String keyword) {
logger.debug("call service keyword : " + keyword);
return keyword;
}
}
단순히 keyword를
받아서
그 keyword를
리턴하는
서비스
클래스이다. 이렇게
작성을
한
후 xml에
설정을
해주어야
한다.
applicationContext.xml
<bean id="rmiSearchService"
class="gseshop.u2search.service.RMISearchServiceImpl">
</bean>
<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
<property name="service" ref="rmiSearchService" />
<property name="serviceName" value="SearchService"></property>
<property name="serviceInterface" value="gseshop.u2search.service.RMISearchService"></property>
</bean>
service 는
실제로
서비스를
구현한
클래스의 id가
되고
serviceName은
클라이언트측에서
호출
할
서비스의
이름이
된다.
serviceInterface는
서비스를
구현한
클래스가 implements 하고
있는
인터페이스가
되고
이
인터페이스는 client측에
제공되어야
한다.
이
외에도 registryPort 와 servicePort도
지정해
줄
수
있다.
이정도면
서비스
제공측에서는
준비가
끝났다.
이제
클라이언트측을
작성해
보자..
RMICallService.java
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public interface RMICallService {
Log logger = LogFactory.getLog(RMICallService.class);
String call(String keyword);
}
RmiCallServiceImpl.java
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class RmiCallServiceImpl implements RMICallService {
Log logger = LogFactory.getLog(RmiCallServiceImpl.class);
RMISearchService rmiSearchService;
public void setRmiSearchService(RMISearchService rmiSearchService) {
this.rmiSearchService = rmiSearchService;
}
public String call(String keyword) {
return rmiSearchService.search(keyword);
}
}
마찬가지로 RMI를
통해
원격의
서비스를
호출하고
그
결과를
리턴하는
간단한
서비스
객체이다.
저
위에
굵게
표시된
부분을
보면, RMI를
통해
원격
호출을
하기
위해
서비스
제공측의 인터페이스를
가지고
있는
것을
알게
된다. 위에서
얘기한
서비스
제공측의
인터페이스가
제공되어야
하는
이유이다.
그리고
웹에서의
사용을
위해
이
클라이언트측
서비스를
호출
할
컨트롤러를
작성해보자..
RemoteCallController.java
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
import gseshop.u2si.service.RMICallService;
@Controller
public class RemoteCallController {
Log logger = LogFactory.getLog(RemoteCallController.class);
RMICallService rmiCallService;
@Autowired
public void setRMICallService(RMICallService rmiCallService) {
this.rmiCallService = rmiCallService;
}
@RequestMapping("/rmicall.gs")
public String search(HttpServletRequest request, HttpServletResponse response) {
logger.debug("controll.....");
String keyWord = request.getParameter("keyword");
String result = rmiCallService.call(keyWord);
ModelAndView mv = new ModelAndView();
mv.setViewName("result");
return result;
}
}
어노테이션을
사용했지만
사실
어노테이션을
사용하면 (심지어
서비스
객체도 @Service를
사용하면 XML 정의가
필요
없다) 코딩은
많이
편한데... 나중에
관리
차원에서는.. 좀
어렵지
않을까
싶기도
하다.. 일단
그래도
어노테이션으로...
그럼
이 controller를
테스트
할
테스트
객체를
만들자..
RmiCallServiceImplTest.java
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.test.AbstractDependencyInjectionSpringContextTests;
public class RmiCallServiceImplTest extends AbstractDependencyInjectionSpringContextTests {
Log logger = LogFactory.getLog(RmiCallServiceImplTest.class);
@Override
protected String[] getConfigLocations() {
return new String[] {"classpath:actions/action-config.xml","classpath:services/serviceContext-sample.xml"};
}
private RemoteCallController rcc;
public void setRemoteCallController(RemoteCallController rcc) {
this.rcc = rcc;
}
public void testCall() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
MockHttpServletResponse response = new MockHttpServletResponse();
request.setParameter("keyword", "나이키");
String result = rcc.search(request, response);
assertEquals("나이키",result);
}
}
AbstractDependencyInjectionSpringContextTests를
상속받아서
구현해
보았다.
앞선
포스트에도
작성했지만 getConfigLocations() 메서드를
통해서
자동적으로
설정되어
있는 bean들을
바인딩
해온다.
Controller가
가지고
있는 Service 객체들
까지..
이제
클라이언트측 XML 설정을
해보면..
applicationContext.xml
<bean id="rmiCall" class="gseshop.u2si.service.RmiCallServiceImpl" >
<property name="rmiSearchService" ref="rmiSearchService1" />
</bean>
<bean id="rmiSearchService1"
class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
<property name="serviceUrl"
value="rmi://localhost/SearchService" />
<property name="serviceInterface"
value="gseshop.u2si.service.RMISearchService" />
</bean>
rmiCall은
클라이언트측에서 RMI 호출을
할
객체이다. 이녀석이
실제로
서비스
제공측의
인터페이스를
가지고
있으므로
그녀석을 Injection 시키기
위해서 property로 지정되어
있다. (rmiSearchService1)
rmiSearchService1은
아래에 설정이
되어
있는데
이
설정을
통해서 RMI를
통해
원격에
있는 RMISearchService의
메서드를
호출
할
수
있게
된다.
테스트를
해보고
실제
서버를
띄워서
해보자..
~~
이참에 봐도봐도 까먹는 자바 RMI를 한번 더 읽어봐야겠다.. 아 이 메멘토 머리통..
'IT노트 > eGov&Spring F/W' 카테고리의 다른 글
[Spring 레퍼런스] 20장 스프링을 사용한 원격작업(remoting) 및 웹 서비스 #1 (0) | 2015.01.30 |
---|---|
★★★★Spring Remote (RMI) 예제 (0) | 2015.01.30 |
Spring + RMI (0) | 2015.01.30 |
Spring ContextLoaderListener context-param 관련 (0) | 2015.01.30 |
Spring Remote (RMI) 예제 (0) | 2015.01.30 |