Whiteship's Note

Spring 컨트롤러와 request scope bean

모하니?/Coding : 2008.04.16 19:07


스프링 컨트롤러와 request scope관한 이메일이 왔습니다.

...

제가 느끼고 있는 궁금증은 Controller 사용시 bean scope에 관한 부분입니다.

몇번의 프로젝트에서  SpringMVC를 이용하여 프로젝트를 했었는데요.
하나의 Controller에서 요청을 처리를 하기 위해 MultiActionController를 사용했습니다.
 
BaseController를 정의해서 BaseController가 MultiActionController를 상속받도록 만들었고,
모든 Controller는 BaseController를 상속 받아 쓰는 형식으로 구조를 잡았습니다.
 
BaseController에는 handleRequestInternal() 메소드를 오버라이드 해서 모든 request 값을
파싱하여 Map에 담도록 해놓았구요. (map에서 값을 꺼내 요청을 처리하도록 말이죠.)
 
테스트를 위해 Controller 내에서 sleep() 을 준 뒤, 몇개의 요청을 날려보면
가장 나중에 요청된 정보로 앞의 정보들이 변경되더군요.
아마도 scope이 singleton이라 그런것 같더군요.
그래서 빈 설정시에 Controller에 대한 scope을 모두 request로 바꿔줬습니다.
 
<bean id="memberController" class="MemberController" scope="request">
 
이렇게 바꾸어주니 이전과 같은 현상은 발생하지 않더군요.

과연 이렇게 하는 것이 맞는 것인지, 아니면 BaseController를 scope="request"로 만들면 그걸
상속받는 다른 빈도 request가 되는 것인지 정확한 판단이 서질 않더군요.

제가 알기로는 Spring에서 Controller 이용시 threadsafe 한 설계는 개발자의 몫이라고 들었습니다.
어디를 봐도 정확한 가이드가 나와있지 않아서 혼자 헤매다 이렇게 메일을 드리게 되었습니다.

...

그리고 다음과 같이 답변해드렸습니다.


request scope 빈을 써본지가 까마득한데 이런 경우에 유용하게 쓸 수 있겠네요. 내용 공유를 허락해주셔서 감사합니다.
top

  1. Favicon of https://jjaeko.tistory.com BlogIcon 째코 2008.04.17 00:26 신고 PERM. MOD/DEL REPLY

    답변 내용의 설정대로라면 싱글톤에서 넌싱글톤 빈을 참조할때 넌싱글톤이 싱글톤처럼 작동되는 문제가 발생하지 않을까요?
    룩업메소드로 빈(파람맵)을 삽입하거나 빈(파람맵)을 <aop:scoped-proxy/> 요소로 생성해서 넣어 주어야 할듯 하네요. 아니면 죄송.. -_-; 하도 오래돼서 생각이 잘..ㅋㅋ

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.04.17 08:17 신고 PERM MOD/DEL

    오.. 맞습니다. 그걸 깜빡했네요.
    <aop:scoped-proxy/> 이걸 넣어줘야 합니다.

  2. 자바지기 2008.04.17 10:13 PERM. MOD/DEL REPLY

    Singleton과 Nonsingleton 사이의 Injection을 처리하기 위해 Method Injection을 사용할 수 있습니다.

    하지만 위의 경우에는 모든 인자를 Map에 담아두는 방법은 썩 적절해보이지는 않네요. Spring MVC에서 제공하는 Command 객체를 활용하는 방식으로 변경하는 것이 원론적인 해결책이 되지 않을까 생각되네요.

    Favicon of https://whiteship.tistory.com BlogIcon 기선 2008.04.17 11:23 신고 PERM MOD/DEL

    넹. Method Injection중에서도 Lookup Method Injection을 사용하면 간단하게 해결할 수 있겠네요.

    흠.. 그런데 그게 될지 잘 모르겠네요.

    CGLIB 사용해서 컨트롤러 상속받아서 Proxy 만들어서 abstract 메소드 구현해서 해당 paramMap 빈 찾아서 넘겨주는걸 스프링이 구현해 줄텐데.. 질문하신 분은 MultiActionController를 사용하고 계셨는데, 그 컨트롤러가 final 메소드를 가지고 있었던 것 같거든요. 그럼 프록시를 못 만들고 에러가 날것 같습니다.

    그냥 2.0부터 스프링이 request scope도 만들어 줬는데 그거 쓰는게 더 쉬운거 같기도 합니다. ^^;;

    Command 객체를 사용하여 Map을 대체하는것이 깔끔하겠네요. 나중에라도 저 클래스에 또 다시 싱글톤이 아닌 객체를 넣어두지 않는 이상은 말이죠..ㅋㅋ

    좋은 댓글 감사합니다. :)

Write a comment.