
Spring을 공부했을 때 이 그림을 정말 많이 보셨을 겁니다. 이 그림에서 제일 중요하다고 생각하는 요소가 있나요? 가장 중요한 요소는 가운데에 위치하고 있는 POJO입니다. POJO는 말 그대로 순수한 자바 오브젝트를 말합니다. POJO는 기술이나 구현에 전혀 얽매이지 않고 그저 순수하게 비즈니스 로직을 위해 존재합니다.
Spring 이전의 EJB는 비즈니스 코드가 기술에 완전히 종속되는 문제가 있었습니다.
public class PostService implements SessionBean {
public void createPost(Post post){
validate(post);
postRepository.save(post);
}
// EJB 규약 때문에 억지로 구현해야 하는 메서드들
@Override public void setSessionContext(SessionContext ctx) throws EJBException { }
@Override public void ejbRemove() throws EJBException { }
@Override public void ejbActivate() throws EJBException { }
@Override public void ejbPassivate() throws EJBException { }
}
이에 대한 반성으로 등장한 개념이 바로 POJO입니다.
그렇다면 왜 POJO가 중요할까요? 이건 Spring만의 생각이 아닙니다.
"Independent of Frameworks. The architecture does not depend on the existence of some library of feature laden software. This allows you to use such frameworks as tools, rather than having to cram your system into their limited constraints."
Uncle Bob의 말에서 알 수 있듯이 프레임워크는 그저 도구로서 존재해야 합니다. Spring도 이 철학을 담아 POJO를 핵심에 두었습니다. 만약 POJO를 위반하게 된다면 어떻게 될까요?
// AOP 없을 때 - 비즈니스 로직이 오염됨
public class OrderService {
public void order(Order o) {
log.info("order 시작"); // 로깅 (비즈니스와 무관)
transaction.begin(); // 트랜잭션 시작 (비즈니스와 무관)
validate(o);
orderRepository.save(o);
transaction.commit(); // 트랜잭션 종료 (비즈니스와 무관)
log.info("order 종료"); // 로깅 (비즈니스와 무관)
}
}
이 코드는 인프라 종속적이고 테스트도 쉽지 않습니다.
public class OrderService {
public void order(Order o) {
validate(o);
orderRepository.save(o);
}
}
// 로깅, 트랜잭션은 Aspect가 외부에서 처리
이 코드를 보면 비즈니스 로직만 남았기 때문에 Spring 없이도 단위 테스트가 가능하고, 로깅 라이브러리를 교체해도 OrderService를 건드릴 필요가 없습니다. 따라서 우리는 AOP, DI/IoC, PSA와 같은 기술은 POJO를 지키기 위한 '도구'라는 것을 알 수 있습니다.
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
https://www.infoq.com/news/2013/07/architecture_intent_frameworks/
https://mangkyu.tistory.com/281
https://jeonyoungho.github.io/posts/Spring-Framework/