티스토리 뷰

발생일: 2009.01.06

문제:
진행 중인 미니 프로젝트에서 웹 어플리케이션이 로딩될 때 설정해야 할 것들이 있다.
여기서는 contextRealRoot 를 메모리에 미리 올려둘 목적으로 쓰려고 하는데,
그 외에도 리소스나, 권한 등 일반적으로도 초기화 때 설정할 사항들이 많다.

스트럿츠 프레임웍의 경우, 웹 어플리케이션의 초기 환경 설정을 위해 PlugIn 기능을 제공한다.


이 기능을 프레임웍이 없는 일반 서블릿 환경에서 가볍게 한 번 구현해 볼까 한다.


해결책:
스트럿츠 프레임웍을 뜯어보지는 않아서 어떻게 구현되어 있는 지는 정확히 모르겠지만,
여기서는 서블릿 컨텍스트 리스너와 옵저버 패턴을 써서 구현했으며, 개략적인 클래스 다이어그램은 아래와 같다.







PlugIn 인터페이스는 옵저버 역할을 하며, init() 메서드를 구현하도록 한다.
init() 메서드에서는 실제 초기화 할 작업을 구현하면 된다.
또한 ConcreatePlugIn 은 PlugIn 인터페이스를 구현한 실제 PlugIn 클래스라고 보면 되겠다.

옵저버 패턴 Subject 역할을 하는 것이 PlugInRepository 이며,
여기서는 PlugIn 을 담아 두고, 알려주는 역할을 한다.
PlugInRepository 의 init() 메서드를 통해 각 PlugIn 의 초기화 작업을 수행할 수 있다.

실제로 컨텍스트가 로드될 때 호출되는 것은 PlugInLoader 클래스이며 서블릿 컨텍스트 리스너이다.
web.xml 에서 <listener-class>로 등록되어 있어 컨텍스트 로드 시점에서 호출되며,
로더에서는 PlugInRepository 과 PlugIn 을 생성하여 등록하고 초기화 시킨다.


전체 코드는 아래와 같다.



초기화 수행 시 필요한 작업들을 PlugIn 객체로 구현한 후,
코드의 PlugInLoader 의 init() 메서드에서처럼 PlugInRepository 에 등록한 후 작업을 호출해주면 된다.

PlugInRepository 의 생성자에 ServletContext 를 넘기도록 한 것은,
PlugIn 객체에서 컨텍스트에 접근할 수 있도록 하기 위해서이다.

실제로 작동시켜 보니 예상했던 대로 잘 작동한다.


몇 가지 기능을 추가로 구현하면, 가벼운 라이브러리로 쓸 수도 있을 것 같다.

#1.
여기서는 추가하려는 PlugIn 객체를 PlugInLoader 에서 직접 추가해줬다.
스트럿츠에서는 수행할 PlugIn 에 대한 정보를 struts-config.xml 에 추가해야 한다.

그렇다면 아예, 특정 인터페이스를 구현한 클래스를 찾는 ClassFinder 따위(검색해보니 좀 있다)를 구현해서,
구현 PlugIn 객체를 자동으로 찾아 호출하도록 하면 더 편리할 것 같다.

사용자 입장에서는 단지 PlugIn 인터페이스만 구현하게 말이다.

#2.
PlugInRepository 는 싱글턴으로 구현해도 괜찮을 것 같다.

#3.
컨텍스트가 종료될 때의 작업을 추가해도 괜찮겠다. (contextDestroyed 시)

#4.
그 외, 예외 처리가 필요하다. (플러그인의 초기화가 실패했을 경우, 로드 자체가 불가능 하게 할 것인가?)

#5.
여기서는 서블릿 컨텍스트 리스너를 이용해서 컨텍스트가 리로드 될 때에도 초기화가 수행된다.
만약, 서버를 올릴 때에만 초기화 하고 싶다면,
    1. 이미 로드되었는지 여부에 대한 flag 를 두어 처리하거나,
        (* 컨텍스트가 리로드 되면, 리스너 클래스 로딩를 새로 하는 모양이다.
            flag 를 static 으로 생성해도 그 값이 저장되지 않는다.)
    2. 컨텍스트 리스너 대신 servlet 의 load-on-startup 값을 1로 설정하면 되겠다.
        (PlugInLoader 를 서블릿으로 구현하고, 서블릿의 init() 메서드 부분을 구현한다.)

반응형
댓글
공지사항