토비의 스프링 - 8장
이번 장에서는 스프링이 무엇이고 스프링이 추구하는 방향성과 마지막으로 스프링의 기술에 대한 내용을 정리해보려고 합니다.
스프링은 다음과 같이 정의하고 있습니다.
"자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량급 어플리케이션 프레임워크"
이를 하나씩 풀어서 적어보면 다음과 같습니다.
- 자바 엔터프라이즈 개발을 편하게 해주는
- 개발자가 복잡하고 실수 하기 쉬운 로우레벨 기술에 많은 신경을 쓰지 않으면서 어플리케이션의 핵심인 비지니스 로직을 빠르고 효과적으로 구현하는 것을 말합니다.
- 오픈소스
- 개발 과정이 공개되어 사용자들이 가진 개발에 관한 의견을 자유롭게 공유하고 토론하며 버그나 신기능에 대한 추가 요청을 할 수 있어 빠르고 유연하게 개발이 가능한 장점과 오픈소스의 특성상 안정적이고 지속적인 개발이 안될 수 있는 단점을 가지고 있다. 하지만 스프링은 이를 이를 전문적으로 개발하는 기업을 만들어 단점을 보완하고 있습니다.
- 경량급
- 만들어진 코드가 지원하는 기술 수준은 비슷하더라도 그것을 훨씬 빠르고 간편하게 작성하게 해줌으로써 생산성과 품질 면에서 유리하다를 표현하는 것이 경량급이라고 합니다.
- 어플리케이션 프레임워크
- 특정 계층이나, 기술, 업무 분야에 국한되지 않고 어플리케이션의 전 영역을 포괄하는 범용적인 프레임워크로 어플리케이션 개발의 전 과정을 빠르고 편리하며 효율적으로 진행 하는걸 목표로 두는 프레임워크
다음은 스프링이 추구하는 방향입니. 그런데 이미 스프링의 방향성이 정의에서 설명이 되어 있습니다.
개발자가 복잡하고 실수 하기 쉬운 로우레벨 기술에 많은 신경을 쓰지 않으면서 어플리케이션의 핵심인 비지니스 로직을 빠르고 효과적으로 구현 해줄 수 있으면서 생산성과 품질면에서 유리하며 어플리케이션 개발의 전 과정을 빠르고 편리하며 효율적으로 진행해 줄 수 있는 프레임워크를 목표로 하고 있습니다.
그런데 왜 개발자가 로우레벨 기술에 신경을 쓰지 않는게 중요할까요? 이는 엔터프라이즈 어플리케이션의 개발이 쉽지 않기 때문이 아닐까요? 그럼 엔터프라이즈 시스템이 무엇이기 때문에 어렵다고 생각하는건지 알아보도록 하겠습니다.
"엔터프라이즈 시스템이란 서버에서 동작하며 기업과 조직의 업무를 처리해주는 시스템"
이런 엔터프라이즈 시스템이 왜 어려운지에 대해서는 다음과 같은 원인이 있다고 합니다.
- 기술적인 제약조건과 요구사항이 늘어가기 때문이다.
- 엔터프라이즈 시스템이 조직의 업무를 처리하면서 점점 기업의 중요한 핵심 정보를 처리하거나 크리티컬한 이슈들을 다루면서 뛰어난 성능과 서비스의 안정성이 요구되게 되었습니다. 또한 기업의 시스템이 복잡도를 높여감으로 순수 비지니스 로직 외의 더 많은 기술조건이 늘어나는데 이는 WAS나 툴을 사용한다고 해결 할 수 있는게 아니라서 개발자와 설계자의 개발 부담이 커져 갔습니다.
- 엔터프라이즈 어플리케이션이 구현해야 할 핵심기능인 비지니스 로직의 복잡함이 증가하기 때문이다.
- 엔터프라이즈 시스템에 업무 의존도가 점점 높아지는데 시대가 발전하면서 업무 프로세스가 바뀌면서 어플리케이션을 수정하는 순간이 자주 오게 되었습니다.
이런 복잡도가 높아지는 이유는 근본적으로 비지니스 로직과 기술 영역의 복잡함이 얽혀있기 때문이라고 사람들은 생각 했고 이를 해결하기 위해 EJB 는 기술적인 코드를 분리해 특정 인터페이스를 구현하고 특정 클래스를 상속하는 등 종속적인 서비스를 통해서만 이를 구현하도록 하면서 더 큰 복잡함을 만들어내게 되었고 스프링은 이런 실패를 교훈삼아 비침투적인 방식으로 기술의 적용 사실을 코드에 직접적으로 반영하지 않는 방식으로 만들어졌습니다.
스프링은 엔터프라이즈 기술을 적용 했을 때의 문제점을 두가지로 분류하고 이에 대한 대응법을 정리했습니다.
- 기술에 대한 접근 방식이 일관성이 없고, 특정 환경에 종속적이다.
- 환경, 서버, 적용 조건이 변경 할 때마다 코드도 바뀐다는건 심각한 문제입니다. 따라서 동일한 목적으로 만들어졌다면 이를 서비스 추상화를 통해 일관성을 만들고 특정 환경에 종속성을 끊어줍니다. 좀 더 자세히 이야기 하면 추상화를 통해 로우레벨의 기술 구현 부분과 기술을 사용하는 인터페이스를 분리하고 환경과 세부 기술에 독립적인 접근 인터페이스를 제공합니다.
- 기술적인 처리를 담당하는 코드가 성격이 다른 코드에 섞여서 등장한다.
- 아무리 서비스 추상화를 하더라도 비지니스 로직 전후로 경계가 설정되야 하는 트랜잭션 같은 기능을 구현하려 하면 복잡도가 증가할 수 밖에 없습니다. 이에 대해 스프링은 AOP 라는 기술 관련 코드를 별도의 모듈로 분리해 관리하는 기술을 사용합니다.
이제 순수한 비지니스 로직을 담은 코드만 존재하게 됩니다. 이는 어플리케이션에서 가장 핵심적인 부분이며 자주 변경되거나 수정되는 부분이기 때문에 대체로 복잡합니다. 그리고 업무가 대체로 어플리케이션에 의존하고 있기 때문에 가장 중요하게 다뤄져야 하는 부분이기도 했습니다.
그래서 예전에는 비지니스 로직의 상당 부분을 DB에 두는 것이 유행했었습니다. 다만 점차 시스템의 규모가 커지고 복잡함이 더 증가함으로 DB에 비지니스 로직을 두는건 불편하고 위험하다고 여겨지기 시작했고, 무엇보다 확장하기 힘들고 많은 비용이 드는 DB에 부담을 계속 주는 것은 문제였고 데이터 엑세스 중심으로 로직을 다루면 유지보수와 테스트면에서 굉장히 어려워 이를 개선하기 위해 비지니스 로직을 어플리케이션 안에서 처리하는 추세로 바뀌기 시작했습니다.
점차 어플리케이션 안에서 비지니스 로직을 처리하게 되니 자바라는 객체지향 언어의 장점을 잘 살리는 것이 비지니스 로직의 복잡함을 깔끔하게 정리하게 되었습니다. 그런 객체지향 언어의 장점을 잘 살린 핵심 도구로 DI가 있습니다.
계속 써오면서 이미 익숙해졌지만 다시 한번 정리하면 DI는 스프링, 자바 공통적으로 사용하는 도구로 특히 스프링의 기술로 이야기 되는 서비스 추상화, 템플릿/콜백, AOP와 같은 것들은 DI 없이는 존재 할 수 없는 기술입니다.
스프링으로 개발을 하다보면 자연스럽게 자주 듣는 이야기 중에 POJO 프로그래밍 이라는 단어가 있습니다. 이는 Plain Old Java Object 의 약자인데 많은 개발자들이 자바의 단순 오브젝트를 사용해 비지니스 로직을 구현하는 편이 나은데 이를 꺼리는 이유를 찾다가 그럴싸한 이름이 없기 때문에 사용하지 않는 것 같다는 생각으로 이름을 지었더니 기대 이상으로 많은 호응을 얻었다고 합니다. 이런 POJO는 세가지 조건을 충족해야만 POJO 라고 불릴 수 있습니다.
- 특정 규약에 종속되지 않는다.
- 자바 언어와 꼭 필요한 API 외에는 종속되지 않아야 한다.
- 특정 환경에 종속되지 않는다.
- 웹이라는 환경정보나 웹 기술을 담고 있는 클래스나 인터페이스를 사용해서는 안된다.
- 어노테이션은 단지 코드로 표현하기에 적합하지 않은 부가정보를 담고 있고 환경에 종속되지만 않는다면 괜찮다.
- 객체지향적인 자바 언어의 기본에 충실해야 한다.
즉, POJO 란 객체지향적인 원리에 충실하면서 환경과 기술에 종속되지 않고 필요에 따라 재활용할 수 있는 방식으로 설계된 오브젝트를 의미합니다.
비지니스 로직과 기술 영역을 분리해 비지니스 로직은 POJO 프로그래밍으로 구현하도록 기술적인 제반을 제공하는 것을 POJO 프레임워크라고 하며 스프링은 POJO 프로그래밍이라고 합니다.
마지막으로 스프링의 기술을 설명하면서 마무리 하도록 하겠습니다.
- 제어의 역전 (IoC) / 의존관계 주입 (DI) : 스프링의 가장 기본이 되는 기술이자 핵심 개발 원칙
- DI 는 유연한 확장을 가능하게 해 OCP(개발 폐쇄 원칙) 라는 객체지향 설계 원칙으로 설명할 수 있습니다.
- DI 를 통해 핵심기능을 담당하는 의존대상의 구현을 바꿀 수 있고 이를 동적으로도 변경이 가능하며 핵심기능을 그대로 둔채 부가기능을 추가 할 수도 있습니다.
- 인터페이스가 호환되지 않는 경우에도 어뎁터 패턴을 이용해 어뎁터 역할을 해주는 레이어를 추가해 클라이언트가 일관성 있게 사용 할 수 있도록 해주는 PSA (서비스 추상화) 와 같은 기술도 있습니다.
- 반복적으로 등장하지만 항상 고정적인 작업의 흐름을 가지고 있다면 자주 바뀌는 부분을 분리해 템플릿/콜백 패턴으로 만들어 DI 를 이용해 매번 만들어야하는 코드를 간결하게 만들기도 합니다.
- 마지막으로 DI를 통해 여러 오브젝트와 협력해 동작하는 오브젝트를 고립시켜 테스트를 용이하게 적용할 수도 있습니다.
- 애스펙트 지향 프로그래밍 (AOP)
- 점점 복잡해져가는 어플리케이션의 요구조건과 기술적 난해함을 객체지향 기술로만 모두 해결하는데에는 한계가 있습니다. AOP 는 이런 한계와 단점을 극복하는데 도움을 주는 보조 프로그래밍 기술 입니다.
- AOP 는 프록시를 사용한 방식과 AspectJ 라는 방식 2가지가 존재합니다.
- 포터블 서비스 추상화 (PSA)
- 환경과 세부 기술의 변화에 관계없이 일관된 방식으로 기술에 접근 할 수 있게 해주는 기술 입니다.