@Configurable 사용해야 하는 이유
DTO를 공부하다가 들었던 의문.. 그동안 내가 만들었던 DO들의 빈약함(Anemic Domain Model)에 대해 명쾌하고 깔끔하게 정리를 해주신 글을 발견했습니다. 그리고 그 대안으로 Rich 또는 Smart DO 그리고 DDD로 이어지는 흐름도 좋은 글입니다. 머리가 맑아지는 동시에 공부할 것들로 머리가 꽉차게 되는 그런 글이기도 합니다.
스프링프레임워크와 DDD(Driven Driven Design)
기존에는 도메인 객체를 모든 레이어에 걸쳐서 사용했었습니다. 그런데 DDD를 하면 도메인이 서비스 계층과 리파지토리 계층 사이에 끼이게 됩니다. 이제 하나의 계층으로 자리를 잡게 되는 것이죠.
출처: https://www.dbguide.net/know/know102001.jsp?mode=view&divcateno=9&divcateno_=9&pg=1&idx=3229
이렇게 되면 도메인 객체에 무언가(DAO나 Repository) 주입시켜주어야 합니다. 그런데.. 이 주입시키는 일 Dependency Injection을 사용하려면 스프링이 관리하는 bean이어야 합니다. 즉 스프링 설정 파일에 도메인 객체가 bean으로 등록되어 있어야 한다는 것이죠. 하지만 문제는 도메인 객체들은 bean으로 설정하여 종속성을 관리할 객체로는 적당하지 않습니다.
이 객체들의 생성을 스프링 컨테이너가 관리할 수 없습니다. 이 객체들은 애플리케이션 동작 중에 생성되기 때문에, 스프링이 생명주기를 관리할 bean으로 등록하여 사용한다는 것은 말이 안됩니다.
이럴 때 등장하는 녀석이 바로 저 @Configurable 애노테이션 입니다. 이녀석이 붙어있는 클래스를 스프링에 등록해두면, 스프링은 그 객체가 생성될 때 그 객체가 필요로 하는 bean들을 주입해 줍니다. 엄청나죠. 이런 일이 어떻게 가능할까요. 바로 AOP 때문에 가능하죠. method 호출 Joinpoint만을 지원하는 스프링 AOP로는 이런 일을 할 수 없습니다. 생성자 실행 Joinpoint를 지원하는 AspectJ가 할 수 있는 일이죠.
그래서 @Configurable을 사용하려면 AsepctJ Load Time Weaver가 필요합니다.
결국 스토리는 이렇게 됩니다.
- DDD를 하고싶어. (도메인 객체가 DAO를 필요로 하고 있어.)
- @Configurable을 사용해야 겠다. (애플리케이션 실행 도중 생기는 객체도 스프링에서 관리할꺼야.)
- LTW가 필요하구나.
아니면 간단하게 다음과 같이 해도 되죠.
- DDD를 하고싶어. (도메인 객체가 DAO를 필요로 하고 있어.)
- 도메인 생성자에서 new 써주지뭐.
아래의 스토리가 더 짧고 간단합니다. 그런데도 저는 첫 번째 스토리대로 하고 싶습니다. 왜냐면, 스프링이 도중에 생겨난 객체들 까지 관리하게 되면, 그 객체들(풍성해진 도메인)에 스프링의 DI와 AOP를 적용할 수 있기 때문이죠. 아래 스토리대로 하면, 도메인 객체가 참조하는 DAO가 바뀌면 소스코드를 매번 바꿔줘야 되겠죠. 그리고 다른 코드는 전부 DI랑 AOP 사용해놓고 도메인 계층만 왕따 시키는 것도 아니고.. 좀 그렇차나요.ㅎㅎ;
그래서.. 좀전까지 @Configurable과 LTW랑 팀을 맺고 저랑 2:1로 씨름을 하고 있었습니다. 제가 졌습니다. 오늘은..-_-;; 잘 안 되더라구요. Eclipse에서 JVM 아규먼트 설정해 주는게 틀렸나.. 왜 그러징;;