Tag Archives: JNDI

CDI vs. JNDI: Type Safety

Java EE 6부터 도입된 CDI 표준은 애플리케이션(예, WAR) 내에서 타입에 기반한 의존성 주입을 가능케 한다. 즉, CDI는 타입 안전성(Type Safety)을 만족시키는 범위 내에서 의존성을 주입할 수 있는 장치를 제공한다.

하지만 CDI의 ‘C’가 나타내는 ‘컨텍스트’란게 최대 단일 애플리케이션의 범위까지 밖에 지원되지 않는다. CDI는 컨테이너가 자동으로 의존성 주입을 수행하기 때문에, 이러한 범위의 제한이 없어진다면 일단 컴포넌트 스캐닝에 따른 복잡도의 증가와 성능의 저하만 하더라도 서버 성능에 큰 악영향을 초래할 수 있을 것이다. 따라서 DI의 범위를 제한하고, 대신 Java EE 환경에서 애플리케이션 간 의존성 관리를 위해서는 서비스 레지스트리의 방식을 사용하는 것이 바람직하다(마틴 파울러의 글을 보면 이런 두 방식에 대한 정리가 잘 돼 있다).

Java EE 환경에서 서비스 레지스트리의 기능을 하는 표준이 바로 JNDI이다. 예를 들어, JNDI의 방식을 사용하면 ‘@Resource’와 같은 어노테이션을 통해 원하는 객체의 참조를 취득할 수 있다. 하지만 JNDI는 반환되는 객체의 타입과 반환된 객체가 저장될 타입의 관계에 대해서는 전혀 고려해주지 않는다. 단지 사전에 등록된 문자열 기반으로 객체를 찾아 넘겨줄 뿐이고, JNDI로부터 넘겨 받은 객체의 타입 안정성을 보장하는 책임은 애플리케이션이 수행해야 한다. 서비스 레지스트리는 DI와는 달리 수동적으로 참조의 등록 및 삭제가 이뤄지기 때문에 올바른 동작이긴 하지만, 그 만큼 프로그래머가 주의해야 하는 요소가 느는 것도 사실이다.

아직 본격적으로 CDI를 사용해볼 일은 없어서 단정 할 수는 없지만, 한 애플리케이션 안에서 JNDI 리소스를 참조할 일이 여럿 있다면 이를 한 곳에 모아서 취득 및 타입 검증의 유지를 분리해 관리하는 편이 좋지 않을까 생각해본다. 이렇게 JNDI를 애플리케이션의 특정 클래스나 팩키지로 분리해 관리토록 한 후에, 취득한 객체의 참조는 다시 CDI를 통해 타입 안정성을 보장해 애플리케이션 내에서 사용토록 할 수 있을 것이다.

타입 안정성은 프로그래밍의 유연성을 낮춘다고 볼 수 있을지도 모르지만, 타입 안정성이 보장되지 않는다면 그 만큼 애플리케이션 코드의 결함 위험이 높아지고 추적성 및 유지보수성은 낮아질 수 밖에 없다. 특히 DI와 같이 의존성을 애플리케이션 코드에서 명시적으로 관리하지 않는 경우에는 타입 안정성의 역할이 더 중요해진다. 타입 안정성에는 나름의 중요성과 장점이 있고 CDI는 이를 지원하고 있다. CDI의 역할과 장점에 대해 잘 파악해서 유용하게 활용할 수 있도록 해봐야겠다.