2015년 5월 20일 수요일

Java Dynamic Proxy vs CGLib Proxy vs AspectJ Weaving #1

모든 것이 그렇지만 기술에 있어서도 기본이 가장 중요한 것 같습니다. 복잡한 기술이라도 기본 원리를 잘 이해하고 있다면 그것을 사용함에 있어서 많은 문제들을 잘 극복하게 해 줄 것입니다.

오늘은 GoF 디자인 패턴 중에서 Proxy 패턴에 대해 알아보고, Proxy 패턴을 구현하는 방법과 어떤 곳에서 활용되고 있는지를 알아보려고 합니다.

Proxy를 사전에 찾아 보면 "대리인" 이라는 뜻을 가지고 있습니다. Proxy 개념을 가장 쉽게 접할 수 있는 것이 Proxy Server가 아닐까 생각이 됩니다.
회사의 사내망은 사설망(Private Network)으로 구성되고 인터넷 망과 연결할 때 보안을 위해 Proxy Server를 두게됩니다. 사내망에서 인터넷으로 나가거나 반대로 인터넷망에서 사내망으로 접속할 때, 모든 통신은 Proxy Server를 거쳐서 이루어 지게 됩니다.
인터넷망에서 사내망을 바라볼 때 사내망 내부는 어떻게 구성되어 있는지 알지 못하고  Proxy Server하고만 통신을 주고 받게 됩니다. 연결을 받아들인 Proxy Server는 사내망안에 대상이 되는 사용자 컴퓨터를 찾아서 연결해 줍니다. 그래서 "대리인"이라는 뜻의 Proxy를 사용하고 있습니다.

프로그래밍에서도 Proxy는 비슷한 개념으로 사용됩니다. 실제 사용할 객체를 대신하여 Proxy 객체가 일을 담당합니다. 이렇게 함으로써 Proxy 객체가 실제 객체에 대한 접근 제어를 할 수 있고, 때로는 실제 객체가 하는 일 외에 추가적인 작업을 할 수 있습니다.

아래 그림에서 Client는 target object의 request() 메쏘드를 호출하지만, 실제는 target object를 감싸고 있는 Proxy 객체가 요청을 가로챈 후에 target object의 request() 메쏘드를 호출합니다.
Client 입장에서는 Proxy가 target object로 보이게 되는 것입니다.


그렇다면 Proxy 패턴은 어떤 경우에 사용이 될까요?

Hibernate나 iBatis/MyBatis를 사용해 본 적이 있다면, lazy loading이라는 말을 들어보았을 것입니다. lazy loading은 실제 데이터베이스에서 데이터를 가져오는 작업을 최대한 늦게 한다는 것입니다. 데이터를 늦게 가지고 온다면, 실제로 프로그램 실행도 늦어지게 됩니다. 그래서 Proxy 객체를 사용해서 마치 데이터베이스에서 데이터를 가져온 것처럼 Proxy 객체를 리턴하고, 실제로 프로그램 로직에서 데이터를 사용해야할 때, Proxy 객체가 target object를 사용해서 데이터베이스에서 데이터를 가져오게 합니다.

또는 Spring AOP(Aspect Oriented Programming) 처럼 비지니스 로직과 트랜잭션(transaction), 로깅(logging) 등 비지니스 로직은 아니지만 프로그램 실행에 있어 꼭 필요한 기능을 비지니스 로직과 분리하여 개발할 때 Proxy 패턴을 사용할 수 있습니다. 다시 말해 어떤 기능에 추가 기능을 넣고 싶은데, 기존 코드를 수정하지 않고 기능을 추가하고 싶을 때 Proxy 패턴을 사용할 수 있습니다.

다음 포스트에서는 Proxy 패턴을 구현하는 방법에 대해서 알아보겠습니다.

댓글 없음:

댓글 쓰기