2013년 4월 30일 화요일

ThreadContext 별 저장소를 활용한 Spring Scope 확장

제가 닷넷으로 개발할 때, IoC/DI framework 으로 Castle.Windsor 를 사용했습니다. NInject, Spring.NET 등도 있었지만... Castle.Windsor 가 가장 앞서 나갔고, Fluent 방식으로 Component 를 등록하는 것도 지원했습니다.

자바에서는 Spring Framework 이 거의 표준이라서 별 생각없이(?) 잘 쓰고 있습니다. 다만 한가지 아쉬운 점은 같은 Thread Context 별로 다른 Bean (Component) 를 사용하고 싶은데... 할 수 있는 것이라곤...
scope 가 singleton 이거나 prototype 이란 거... 즉 프로세스에 오직 하나의 인스턴스만 있거나, 요청 시 매번 새로운 인스턴스를 준다는 것이지요. 물론 웹에서는 PerSession 등이 있습니다만, 내부 라이브러리에서는 Thread Context 별로 Bean을 제공하는 방식이 추가되었으면 좋겠다 싶었습니다.

Windsor Castle 에는 thread 라고 지정해주면 Thread Context 별로 독립된 인스턴스를 제공해 주거든요^^

그래서 만들어 봤습니다.

우선 Bean 을 정의하는데, 일반적으로 단순 생성해서 주는 게 아니라. TheadLocal을 이용하여, 생성된 인스턴스를 보관하여, 같은 ThreadContext 에서 Bean을 요청하는 경우, 기존 인스턴스를 제공하는 것입니다.

ThreadLocal 에 초기 값을 지정해주고, 필요 시마다 ThreadLocal 의 인스턴스를 제공해 주는 것입니다.
이렇게 하면, Thread Context 별로 다른 인스턴스를 사용하여, 독립적인 작업을 수행할 수 있고,   같은 Thread Context에서는 반복적인 조회에도 같은 인스턴스를 제공할 수 있습니다.

Thread 별로 제공해야 하는 Bean 이 많은 경우에는 위와 같은 작업이 번거로울 수 있습니다. 이럴 때에는 thread 별로 hash map 을 제공하는 것이 좋습니다.

위와 같이 같은 Thread 에서는 하나의 hash map 을 공유하게 되므로, 여러 Class 들간에 인자 전달 방식이 아니더라도, thread 단위로 값을 공유할 수 있습니다.

이렇게 Local 을 이용하여 기존 ThreadLocal 방식을 다시 구현하면


과 같습니다. Bean 마다 ThreadLocal 을 따로 만들지 않아 좋은 장점이 있습니다.

댓글 없음: