2010년 3월 18일 목요일

Spring Bean Seesion,Request Scope

스프링에서 제공하는 bean은 아래와 같이 life cycle를
가지고 있습니다.
singleton,prototype,request,session,global session
오늘 이중에서 request와 session scope에 대해서 말씀
드리겠습니다.
먼 저 두 scope에 대해서 간단히 설명하면 이름에서
알 수 있듯이 bean의 생명 주기를 말합니다.
즉 request scope은 HTTP Request 요청시 생성이 되며,
Response할 때 빈이 소멸 됩니다.
Session도 Http 세션에서 생성시 생성되면 세션이
종료되면 소멸 됩니다.
그러면 이런한 bean scope은 언제 설정해야 할까요?
개발을 하다 보면 HttpServletRequest 객체를

  • Use Case Request Scope

Controller 에서 Service로 넘길 때가 있습니다.
(물론 Controller에서 도메인으로 auto binding을 하겠죠^^)
일 반적으로 2가지 방법을 사용 할 것입니다.
하나는 request객체를 Service로 직접 넘기는 방법과
request 객체를 도메인 객체에 setter 함수를 통해서
Service로 넘길 것입니다.




@RequestMapping("/member.beyondje22")
public String list(HttpServletRequest request) {
// case1....
this.memberService.list(request);
// case2....
HttpDomain httpDomain = new HttpDomain();
httpDomain.setId(request.getParameter("id"));
this.memberService.list(httpDomain);
return "/member/list.jsp";
}

먼 저 첫번째 방법은 개인적으로 비추입니다.
이유인즉 Service 객체는 pure하게 설계가
되어야 하기 때문이죠 .
두 번째 방법은 좀 고급 스럽지가 못하죠
그래서 좀더 고급 스럽게 유연하게 request
scope을 통해서 구현해 보겠습니다.

==MemberController 클래스


   private HttpDomain httpDomain;

public void setHttpDomain(BaseDao httpDomain) {
this.httpDomain = httpDomain;
}

@RequestMapping("/member.beyondje22")
public String list(HttpServletRequest request) {
this.httpDomain.setId(request.getParameter("id"));
this.memberService.list();
return "/member/list.jsp";
}

== MemberService 클래스

   private HttpDomain httpDomain;

public void setHttpDomain(BaseDao httpDomain) {
this.httpDomain = httpDomain;
}

public void list() {
System.out.println("====" + this.httpDomain.getId());
}

빈 설정을 아래와 같이 합니다.

<bean id="httpDomain" class="org.beyondj2ee.HttpDomain" scope="session">
<aop:scoped-proxy/>
</bean>


<bean id="memberController" class="org.beyondj2ee.MemberController">
<property name="httpDomain" ref="httpDomain">
</property>
........
</bean>

<bean id="memberService" class="org.beyondj2ee.MemberServiceImpl">
<property name="httpDomain" ref="httpDomain">
</property>
</bean>



소스를 보시면 서로 간에 coupling 없이 injection을
통해서 Controller,Service,DAO 클래스에서
참조가 가능 합니다.Session Scope Bean도
단지 생명 주기가 차이날뿐 똑같이 사용할 수 있습니다.

  • 설정 방법
request와 session scope을 사용 하려면 웹 어플리케이션에서만
사용해야 합니다. standalone 형태의 스프링 어플리케이션에서는
지원을 하지 않습니다.
스프링 IoC 컨테이너에게 나는 웹 어플리케이션 이라고
선언을 web.xml에서 선언 해야 합니다.
기본적으로 Spring MVC를 사용한다면 별다른 설정이
필요 없습니다. 이유인즉 "DispatcherServlet" 에서
자동으로 설정하기 때문입니다. 만약 다른 MVC
(struts,struts2,webwork)를 사용하고
Servlet2.4 버전일 경우
아래와 같이설정 합니다.



<web-app>
...
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
...
</web-app>


2.3 버전일 경우

<web-app>
..
<filter>
<filter-name>requestContextFilter</filter-name>
<filter-class>org.springframework.web.filter.RequestContextFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>requestContextFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
</web-app>

  • 빈 설정 하기

반드시 "aop:scoped-proxy" 태그를 설정해야 합니다.
이유인즉은 이 빈들을 참조하는 빈들이 생성될때
같이 생성이 됩니다. 그럴경우 Http 객체를
참조 할 수 없습니다. 그래서 이러한 빈들은
http 이벤트가 발생시 proxy 객체를 통해서
생성이 됩니다.
그리고 위와같이 선언하면 반드시
"CGLIB" 라이브러리가 클래스 패스로 잡혀 있어야 합니다.
만약 JDK에서 지원되는 proxy를 사용 하려면

<aop:scoped-proxy class="false"/>
선언 합니다.
개인적인 의견은 request scope은 잘 사용되지 않을 것
같지만 session scope은 매우 유용할 듯 합니다.

댓글 없음:

댓글 쓰기