스프링의 정의
스프링이란 어떤 것이다라고 한마디로 정의하기는 쉽지 않다. 스프링에 대해 가장 잘 알려진 정의는 이렇다. 자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량급 애플리케이션 프레임워크
애플리케이션 프레임워크
•
일반적으로 라이브러리나 프레임워크는 특정 업무 분야나 한 가지 기술에 특화된 목표를 가지고 만들어진다.
•
스프링은 이와 다르게 ‘애플리케이션 프레임워크’라는 특성을 가진다.
•
애플리케이션 프레임워크는 특정 계층이나, 기술, 업무 분야에 국한되지 않고 애플리케이션의 전 영역을 포괄하는 범용적인 프레임워크를 말한다.
•
애플리케이션 프레임워크는 애플리케이션 개발의 전 과정을 빠르고 편리하며 효율적으로 진행하는데 일차적인 목표를 두는 프레임워크다.
경량급
•
스프링이 경량급이라는 건 스프링 자체가 아주 가볍다거나 작은 규모의 코드로 이뤄졌다는 뜻은 아니다.
•
여기서 스프링이 가볍다는 이유는 불필요하게 무겁지 않다는 의미다.
◦
프링이 처음 등장하던 시절의 자바 주류 기술이었던 예전의 EJB 같은 과도한 엔지니어링이 적용된 기술과 스프링을 대비시켜 설명하려고 사용했던 표현이다.
•
스프링은 가장 단순한 서버환경인 톰캣(Tomcat)이나 제티(Jetty)에서도 완벽하게 동작한다.
•
스프링은 군더더기 없이 깔끔한 기술을 가진 ‘경량급’ 프레임워크라고 불린 것이다.
자바 엔터프라이즈 개발을 편하게
•
스프링은 근본적인 부분에서 엔터프라이즈 개발의 복잡함을 제거해내고 진정으로 개발을 편하게 해주는 해결책을 제시한다.
•
스프링은 EJB의 잘못된 접근 방법에 대한 대안을 모색하는 중에 등장했다.
오픈소스
•
스프링은 오픈소스로 개발되어 얼마든지 가져다 자유롭게 이용해도 된다.
•
비교적 사용이 매우 자유로운 아파치 2.0 라이선스를 따르고 있다.
•
오픈소스 개발 방식의 가장 큰 취약점은 지속적이고 안정적인 개발이 계속될지가 불확실하다는 것
◦
스프링은 오픈소스지만 사용자에게 지속적인 신뢰를 줄 수 있도록 개발을 책임지고 진행할 수 있는 스프링소스라는 전문 기업이 있다
스프링의 목적
엔터프라이즈 개발의 복잡함
엔터프라이즈 개발이 복잡한 이유는 크게 두 가지 원인을 생각해볼 수 있다.
•
기술적인 제약 조건과 요구사항이 늘어가기 때문
•
엔터프라이즈 애플리케이션이 구현해야 할 핵심기능인 비즈니스 로직의 복잡함이 증가하기 때문
복잡함을 가중시키는 원인은 비즈니스 로직의 복잡함과 기술적인 복잡함이다.
•
세부 요소가 이해하기 힘든 방식으로 얽혀 있고, 그 때문에 쉽게 다루기 어렵다는 의미
•
엔터프라이즈 시스템 개발이 어려운 가장 큰 이유는 근복적인 비즈니스 로직과 엔터프라이즈 기술이라는 두 가지 복잡함이 한데 얽혀 있기 때문
복잡함을 해결하려는 도전
제거될 수 없는 근본적 복잡함
•
근본적으로 엔터프라이즈 개발에 나타나는 복잡함의 원인은 제거대상이 아님
•
대신 그 복잡함을 효과적으로 상대할 수 있는 전략과 기법이 필요
•
문제는 비즈니스 로직의 복잡함 다루는 방법과 기술적인 복잡함을 효과적으로 처리하는 방법이 다르다는 점
•
따라서 가장 먼저 할 일은 성격이 다른 이 두가지 복잡함을 분리하는 것
실패한 해결책 : EJB
•
EJB의 기본 전략은 이 두가지 종류의 복잡함을 분리하는 것이었음
•
EJB는 기술적인 복잡함을 애플리케이션의 핵심 로직에서 일부분 분리하는데 성공하긴 함
•
하지만 EJB는 특정 클래스를 상속함으로써 객체지향의 특성을 잃어버리게 되었다.
비침투적인 방식을 통한 효가적인 해결책 : 스프링
•
EJB처럼 어떤 기술을 적용했을 때 그 기술과 관련된 코드나 규약 등이 코드에 등장하는 경우를 침투적인 기술이라함
•
비침투적인 기술은 기술의 적용사실이 코드에 직접 반영되지 않는 특징을 가짐
•
스프링은 비침투적인 기술 전략을 택함으로서 꼭 필요한 경우 조차도 코드에 노출되지 않도록 만들어 줌
•
스프링을 적용한다고 근복적인 복잡함이 사라진건 아니지만, 성격이 다른 복잡함을 분리하여 각각 효과적으로 상대할 수 있는 기반을 마련해 줌
복잡함을 상대하는 스프링의 전략
기술적 복잡함을 해결하려는 전략
•
기술에 대한 접근 방식이 일관성이 없고, 특정 환경에 종속적이다.
◦
일괄성 없는 기술과 서버환경의 변화에 대한 스프링의 공략 방법은 서비스 추상화
◦
스프링이 제공하는 템플릿/콜백 패턴은 판에 박힌 반복적인 작업 흐름과 API 사용 코드를 제거해줌
•
기술적인 처리를 담당하는 코드가 성격이 다른 코드에 섞여서 등장한다.
◦
기술과 비즈니스 로직의 혼재로 발생하는 복잡함을 해결하기 위한 스프링의 접근방법은 AOP
◦
AOP는 최후까지 애플리케이션 로직을 담당하는 코드에 남아 있는 기술 관련 코드를 깔끔하게 분리해서 별도의 모듈로 관리하게 해주는 강력한 기술임
비즈니스와 애플리케이션 로직의 복잡함을 상대하는 전략
•
비즈니스 로직의 복잡함을 상대하는 전략은 자바라는 객체지향 기술 그 자체다. 스프링은 단지 객체지향 언어의 장점을 제대로 살리지 못하게 방해했던 요소를 제거하도록 도와줄 뿐이다.
핵심 도구 : 객체지향과 DI
•
객체지향 설계 기법을 잘 잘 적용할 수 있는 구조를 만들기 위해 DI와 같은 유용한 기술을 편하게 적용하도록 도와주는 것이 스프링의 기본 전략
•
DI란 특별한 기술이라기보다는 유연하게 확장할 수 있는 오브젝트설계를 하다 보면 자연스럽게 적용하게 되는 객체지향 프로그래밍 기법
•
스프링은 단지 그것을 더욱 편하고 쉽게 사용하도록 도와줄 뿐
•
결국 스프링의 기술과 전략은 객체지향이라는 자바 언어가 가진 강력한 도구를 극대화해서 사용할 수 있도록 돕는 것
•
스프링만 잘 공부하면 자바언어 자체나 객체지향 설계와 개발 실력 따윈 신경쓰지 않아도 복잡한 시스템 개발을 잘할 수 있으리라 생각하면 오산
POJO 프로그래밍
스프링 핵심 개발자들은 “스프링의 정수(essence)”는 엔터프라이즈 서비스 기능을 POJO에 제공하는 것”이라함
스프링의 핵심 : POJO
스프링의 주요 기술인 IoC/DI, AOP, 서비스추상화는 애플리케이션을 POJO로 개발할 수 있게 해주는 가능기술이라고 불린다.
POJO란 무엇인가?
POJO는 Plain Old Java Object의 첫 글자를 따서 만든 약자다.
POJO의 조건
단순하게 보자면 그냥 평범한 자바오브젝트라고 할 수 있지만 좀 더 명확하게 하자면 적어도 다음의 조건을 충족해야 POJO라고 불릴 수 있음
•
특정 규약에 종속되지 않는다.
◦
POJO는 자바 언어와 꼭 필요한 API이외엔 종속되지 않아야 한다.
•
특정 환경에 종속되지 않는다.
◦
특정 환경에 종속적이어야만 동작하는 오브젝트도 POJO라고 할 수 없다.
진정한 POJO란 객체지향적인 원리에 충실하면서, 환경과 기술에 종속되지 않고 필요에 따라 재활용 될 수 있는 방식으로 설계된 오브젝트를 말한다.
POJO의 장점
POJO가 될 수 있는 조건이 그대로 POJO의 장점이 된다.
•
특정한 기술과 환경에 종속되지 않는 오브젝트는 그만큼 깔금한 코드가 될 수 있다.
•
POJO로 개발된 코드는 자동화된 테스트에 매우 유리하다
•
객체지향적인 설계를 자유롭게 적용할 수 있다는 것도 큰 장점이다.
POJO 프레임워크
스프링은 POJO를 이용한 엔터프라이즈 애플리케이션 개발을 목적으로 하는 프레임워크이다.
스프링을 이용하면 POJO 프로그래밍의 장점을 그대로 살려서 엔터프라이즈 애플리케이션의 핵심 로직을 객체지향적인 POJO를 기반으로 깔끔하게 구현하고, 동시에 엔터프라이즈 환경의 각종 서비스와 기술적인 필요를 POJO 방식으로 만들어진 코드에 적용할 수 있다.
스프링은 비즈니스 로직의 복잡함과 엔터프라이즈 기술의 복잡함을 분리해서 구성할 수 있게 도와준다. 하지만 자신은 기술영역에만 관여하지 비즈니스 로직을 담당하는 POJO에서는 모습을 감춘다.
스프링의 기술
제어의 역전(IoC) / 의존관계 주입(DI)
•
핵심기능의 변경
◦
DI의 가장 대표적인 적용 방법은 바로 의존 대상의 구현을 바꾸는 것
◦
실제 의존하는 대상이 가진 핵심기능을 DI 설정을 통해 변경하는 것이 대표적인 DI의 활용 방법
•
핵심기능의 동적인 변경
◦
의존 오브젝트의 핵심 기능 자체를 바꾸는 것
◦
일단 DI 되고 나면 그 후로는 바뀌지 않는다. 즉 동적인 방식으로 연결되지만 한 번 DI되면 바뀌지 않는 정적인 관계를 맺어주는 것
◦
하지만 DI를 잘 활용하면 애플리케이션이 동작하는 중간에 그 의존 대상을 다이내믹하게 변경할 수 있음
•
부가기능의 추가
◦
핵심기능은 그대로 둔 채로 부가기능을 추가하는 것
◦
데코레이터 패턴을 생각해보면 된다. 인터페이스를 두고 사용하게 하고, 실제 사용할 오브젝트는 외부에서 주입하는 DI를 적용해두면 데코레이터 패턴을 쉽게 적용할 수 있다.
•
인터페이스의 변경
◦
사용하려고 하는 오브젝트가 가진 인터페이스가 클라이언트와 호환되지 않는 경우가 있다.
◦
이렇게 클라이언트가 사용하는 인터페이스와 실제 오브젝트 사이에 인터페이스가 일치하지 않는 경우에도 DI가 유용하다.
•
프록시
◦
필요한 시점에서 실제 사용할 오브젝트를 초기화하고 리소스를 준비하게 해주는 지연된 로딩(lazy loading)을 적용하려면 프록시가 필요함
•
템플릿과 콜백
◦
템플릿/콜백 패턴은 DI의 특별한 적용 방법
◦
반복적으로 등장하지만 항상 고정적인 작업 흐름과 그 사이에서 자주 바뀌는 부분을 분리해서 템플릿과 콜백으로 만들 고 이를 DI 원리를 응용해 적용하면 지저분하게 매번 만들어야 하는 코드를 간결하게 만들 수 있다.
•
싱글톤과 오브젝트 스코프
◦
DI가 필요한 중요한 이유 중 한 가지는 DI 할 오브젝트의 생명주기를 제어할 수 있다는 것
◦
오브젝트의 생성부터 관계 설정, 이용, 소멸에 이르기까지의 모든 과정을 DI 컨테이너가 주관하기 때문에 그 오브젝트의 스코프를 자유롭게 제어할 수 있다.
◦
컨테이너가 알아서 싱글톤으로 만들고 관리하기 때문에 클래스 자체는 싱글톤을 고려하지 않고 자유롭게 설계해도 된다는 장점이 있다.
•
테스트
◦
다른 오브젝트와 협력해서 동작하는 오브젝트를 효과적으로 테스트하는 방법은 가능한 한 고립시키는 것
◦
다른 오브젝트와의 사이에서 일어나는 일을 테스트를 위해 조작할 수 있도록 만든다.
◦
복잡한 테스트할 대상에 의존하는 오브젝트를, 테스트를 목적으로 만들어진 목 오브젝트로 대체하면 유용하다.
애스펙트 지향 프로그래밍(AOP)
AOP도 스프링의 3개 기술중의 하나다.
애스펙트 지향 프로그래밍은 객체지향 프로그래밍(OOP)처럼 독립적인 프로그래밍 패러다임이 아니다. AOP와 OOP는 서로 배타적이 아니라는 말이다.
스프링의 AOP는 스프링이 POJO프로그래밍을 지원하려고 그 핵심 목적을 위해 중요한 역할을 하고있다.
AOP 적용 기법
AOP를 자바 언어에 적용하는 기법은 크기 두 가지로 분류할 수 있다.
•
스프링과 같이 다이내믹 프록시를 사용하는 방법
◦
기존 코드에 영향을 주지 않고 부가기능을 적용하게 해주는 데코레이터 패턴을 응용한 것
◦
패턴을 활용하기 때문에 만들기 쉽고 간편
◦
부가기능을 부여할 수 있는 곳은 메소드의 호출이 일어나는 지점뿐이라는 제약이 있음
•
자바 언어의 한계를 넘어서는 언어의 확장을 이용하는 방법
◦
AspectJ라는 유명한 오픈소스 AOP 툴이 있음
◦
AspectJ는 프록시 방식의 AOP에서는 불가능한 다양한 조인포인트를 제공
◦
메소드 호출뿐 아니라 인스턴스 생성, 필드 액세스, 특정 호출 경로를 가진 메소드 호출 등에도 부가기능을 제공
◦
AOP 컴파일러를 이용한 빌드 과정을 거치거나, 클래스가 메모리로 로딩될 때 그 바이트 코드를 조작하는 위빙과 같은 별도의 방법을 이용해야 함
AOP 적용 단계
1.
미리 준비된 AOP 이용
2.
전담팀을 통한 정책 AOP 활용
3.
AOP의 자유로운 이용
포터블 서비스 추상화(PSA)
세 번째 기능기술은 환경과 세부 기술의 변화에 관계없이 일관된 방식으로 기술에 접근 할 수 있게 해주는 PSA(Portable Service Abstraction)다.
POJO로 개발된 코드는 특정 환경이나 구현 방식에 종속적이지 않아야 한다.
스프링이 제공하는 대표적인 기술이 바로 일관성 있는 서비스 추상화 기술이다.