스프링의 정의스프링의 목적비침투적인 방식을 통한 효과적인 해결책 : 스프링기술적 복잡함을 상대하는 전략 (서비스 추상화, AOP)비즈니스 로직의 복잡함을 상대하는 전략 → 자바라는 객체지향 기술 그 자체스프링의 핵심 : POJOPOJO의 조건POJO의 장점스프링의 기술IoC/DIDI의 활용 방법AoPPSA(Portable Service Abstraction)
스프링의 정의
자바 엔터프라이즈 개발을 편하게 해주는 오픈소스 경량급 애플리케이션 프레임워크
애플리케이션 프레임워크
- 일반적으로 라이브러리나 프레임워크는 특정 업무 분야나 한 가지 기술에 특화된 목표를 갖고 만들어짐
- 예를 들어 웹 계층을 MVC 구조로 손쉽게 만들 수 있게 한다거나
- 간단한 설정만으로 관계형 DB와 자바오브젝트를 매핑해주는 ORM 기술을 제공해 준다거나.
- 하지만 스프링은 이와 다르게
애플리케이션 프레임워크
라는 특징을 갖고 있음
- 애플리케이션의 전 영역을 관통하는 일관된 프로그래밍 모델과 핵심 기술을 바탕으로 해서 각 분야의 특성에 맞는 필요를 채워주고 있기에, 애플리케이션을 빠르고 효과적으로 개발할 수 있음
- 스프링의 일차적인 존재 목적은, 핵심 기술에 담긴 프로그래밍 모델을 일관되게 적용해서 엔터프라이즈 애플리케이션 전 계층과 전 영역에 전략과 기능을 제공해줌으로써 애플리케이션을 편리하게 개발하게 해주는 애플리케이션 프레임워크로 사용되는 것임
경량급
- 스프링이 나오기 전의 자바 주류 기술이었던 EJB 같은 과도한 엔지니어링이 적용된 기술과 스프링을 대비시켜 설명하려고 사용됐던 표현
- 기술수준이 가볍다거나, 스프링의 용도가 제한적이라는 의미가 결코 아님
자바 엔터프라이즈(Java EE) 개발을 편하게
- 자바 엔터프라이즈 : 기업의 요구사항을 만족시키는 애플리케이션
- 편리한 애플리케이션 개발이란 개발자가 복잡하고 실수하기 쉬운 로우레벨 기술에 많은 신경을 쓰지 않으면서도 애플리케이션의 핵심인 사용자의 요구사항, 즉 비즈니스 로직을 빠르고 효율적으로 구현하는 것을 말함
- 엔터프라이즈 개발에서 필연적으로 요구되는 기술적인 요구를 충족하면서도 개발을 복잡하게 만들지 않는다는 점이 뛰어난 면
- JAVA SE(Standard Edition)
- Java 프로그래밍 언어의 기본 유형 및 개체에서 네트워킹, 보안, 데이터베이스 액세스, 그래픽 사용자 인터페이스(GUI) 개발 및 XML 구문 분석에 사용되는 고급 클래스에 이르기까지 모든 것을 정의
- JDBC와 GUI, 네트워크 등 각종 API를 이용해서 개발이 가능합니다.
- Java EE(Enterprise Edition)
- Java EE 플랫폼은 Java SE 플랫폼 위에 구축
- Java EE 플랫폼은 대규모, 다계층, 확장 가능하고 안정적이며 안전한 네트워크 애플리케이션을 개발하고 실행하기 위한 API 및 런타임 환경을 제공
- WEB개발을 하기 위해 JavaEE로 개발을 진행
- 이는 Servlet과 JSON, REST 반응형 클라이언트 API, 웹소켓 등을 지원하기 때문이다.
스프링의 목적
- 모든 기술이나 지식이 다 그렇지만, 스프링은 더더욱 그 목표를 분명히 알고 사용하지 않으면 그 가치를 제대로 얻기 힘듦
- 스프링을 사용해서 엔터프라이즈 애플리케이션 개발을 편하게 하려는 이유는?? 원래 엔터프라이즈 개발이란 편하지 않기 때문임.
엔터프라이즈 개발의 근본적인 복잡함의 이유
- 기술적인 제약조건과 요구사항이 늘어가기 때문
- 엔터프라이즈 시스템이란 서버에서 동작하며 기업과 조직의 업무를 처리해주는 시스템
- 엔터프라이즈 시스템은 많은 사용자의 요청을 동시에 처리해야 하기에 서버의 자원을 효율적으로 공유하고 분배해서 사용할 수 있어야 함
- 중요한 기업의 핵심 정보를 처리하거나 미션 크리티컬한 금융, 원자력, 항공, 국방 등의 시스템을 다루기도 하기에
보안
,안정성
,확장성
면에서도 뛰어나야 함 - ⇒ 뛰어난 성능과 서비스의 안정성이 요구되고 그것을 고려한 개발 기술이 필요, 기술적 고려 사항이 많음
- 기업의 시스템이 복잡함에 따라 다중 데이터베이스를 하나의 트랜잭션으로 묶어서 사용하는 분산 트랜잭션 지원도 필요
- 엔터프라이즈 애플리케이션이 구현해야 할 핵심기능인 비즈니스 로직의 복잡함이 증가하기 때문
- 복잡함을 가중시키는 원인 : 근본적인
비즈니스 로직
과엔터프라이즈 기술
이라는 두 가지 복잡함이 한데 얽혀있기 때문 - 각종 엔터프라이즈 기술 서비스를 적용하기 위한 코드와 각종 기술적인 API의 호출 코드를 비즈니스 로직에 대한 구현 코드와 함께 덕지덕지 붙여서 만드는 것은 매우 어려움
- 더 큰 문제는 이렇게 복잡하게 엉켜있는 코드를 유지보수하는 일임. 하나의 수정 요구를 적용하다가 새로운 버그를 만들 수 있음
비침투적인 방식을 통한 효과적인 해결책 : 스프링
- 꼭 필요한 기능을 사용하는 것도 아니면서 단지 어떤 기술을 바탕으로 만들어진다고 해서 특정 클래스나 인터페이스 API 등이 코드에 마구 등장한다면 그것은 침투적인 기술이 되며 복잡함을 가중시키는 원인이 됨
- 반면 비침투적인 기술은 기술의 적용 사실이 코드에 직접 반영되지 않음
- 스프링을 이용하면 기술적인 복잡함과 비즈니스 로직을 다루는 코드를 깔끔하게 분리할 수 있다.
기술적 복잡함을 상대하는 전략 (서비스 추상화
, AOP
)
기술에 대한 접근 방식이 일관성이 없고 특정 환경에 종속적임 ⇒ 서비스 추상화로 해결
- 일관성 없는 기술과 서버환경의 변화에 대한 스프링의 공략 방법은 바로
서비스 추상화
임
- 기술적 복잡함을 추상화를 통해 로우레벨의 기술 구현 부분과 기술을 사용하는 인터페이스를 분리하고, 환경과 세부기술에 독립적인 접근 인터페이스를 제공하는 것이 가장 좋은 해결책임
- 데이터 액세스 예외에 대한 추상화는 비즈니스 로직을 담은 서비스 레이어의 코드가 특정 기술이 발생시키는 예외에 종속되지 않고, 불필요하게 예외를 잡아야 하거나 throws를 선언해야 하는 것을 방지해줌
기술적인 처리를 담당하는 코드가 성격이 다른 코드에 섞여서 등장 ⇒ AOP 로 해결
- 비즈니스 로직 전후로 경계가 설정되어야 하는 트랜잭션, 비즈니스 로직에 대한 보안 적용, 계층 사이에 주고받는 데이터와 예외의 일괄 변환이나 로깅이나 감사 등이 대표적인 예
- 이런 기술과 비즈니스 로직의 혼재로 발생하는 복잡함을 해결하기 위한 스프링의 접근방법 → AOP
비즈니스 로직의 복잡함을 상대하는 전략 → 자바라는 객체지향 기술
그 자체
- 스프링은 단지 객체지향 언어의 장점을 제대로 살리지 못하게 방해했던 요소를 제거하도록 도와줄 뿐
- 핵심 도구 : 객체지향과 DI
- 기술적인 복잡함을 해결하는 문제나 기술적인 복잡함이 비즈니스 로직에 침범하지 못하도록 분리하는 경우에도 DI가 바탕이 된 여러 가지 기법이 활용됨
- 반면 비즈니스 로직 자체의 복잡함을 해결하려면 DI 보다는 객체지향 설계 기법이 더 중요함
- 결국 모든 스프링의 기술과 전략은 객체지향이라는 자바 언어가 가진 강력한 도구를 극대화해서 사용할 수 있도록 돕는것이다!! 스프링은 단지 거들 뿐
스프링의 핵심 : POJO

- 스프링 애플리케이션은 POJO를 이용해서 만든 애플리케이션 코드와 POJO가 어떻게 관계를 맺고 동작하는지를 정의해놓은 설계정보로 구분된다.
- DI의 기본 아이디어는 유연하게 확장가능한 오브젝트를 만들어두고 그 관계는 외부에서 다이내믹하게 설정해준다는 것
- 이런 DI의 개념을 애플리케이션 전반에 걸쳐 적용하는 것이 스프링의 프로그래밍 모델
POJO의 조건
특정 규약에 종속되지 않는다
- POJO는 자바 언어와 꼭 필요한 API 외에는 종속되지 않아야 한다.
- 특정 규약을 따라 만들게 하는 경우는 대부분 규약에서 제시하는 특정 클래스를 상속하도록 요구한다.
- 그럴 경우 자바의 단일 상속 제한 때문에 클래스에 객체지향적인 설계 기법 적용하기가 어려워지는 문제가 생김
- 또한 규약이 적용된 환경에 종속적이게 되기 때문에 다른 환경으로 이전이 힘들다는 문제점이 있음
특정 환경에 종속되지 않는다
- 예를들어 WebLogic 서버에서만 사용 가능한 API를 직접 쓴 코드를 갖고 있거나 특정 OS에서 제공되는 기능을 직접 호출하도록 만들어진 오브젝트 등
- 이런 식으로 순수한 애플리케이션 로직을 담고 있는 오브젝트 코드가 특정 환경에 종속되게 만드는 경우라면 그것 역시 POJO 라고 할 수 없다.
- 비즈니스 로직을 담고 있는 POJO 클래스는 웹이라는 환경 정보나 웹 기술을 담고 있는 클래스나 인터페이스를 사용해서는 안됨. 그렇게 했을 시, 웹 외의 클라이언트가 사용하지 못하게 되기에
- 또한 웹 서버에 올리지 않고 독립적으로 테스트하기도 힘들어짐
- 요즘은 소스코드에 직접 메타정보를 추가해주는 애노테이션을 많이 사용하는데, 애노테이션이 단지 코드로 표현하기에 적절치 않은 부가적인 정보를 담고 있고, 그 때문에 환경에 종속되지만 않는다면 여전히 POJO라고 할 수 있음
- 하지만 애노테이션이나 엘리먼트 값에 특정 기술과 환경에 종속적인 정보를 담고 있다면 그때는 POJO로서의 가치를 잃어버린다고 할 수 있다.
특정 기술규약과 환경에 종속되지 않으면 모두 POJO 인가? 그렇지 않다
진정한 POJO란 객체지향적인 원리에 충실하면서, 환경과 기술에 종속되지 않고 필요에 따라 재활용될 수 있는 방식으로 설계된 오브젝트를 말함
POJO의 장점
- 특정한 기술과 환경에 종속되지 않는 오브젝트는 그만큼 깔끔한 코드가 될 수 있음
- 자동화된 테스트에 매우 유리
- 객체지향적인 설계를 자유롭게 적용할 수 있다는 것도 큰 장점
- 로드 존슨은 대규모 자바 엔터프라이즈 시스템을 개발해온 수많은 경험을 통해 자바 언어의 객체지향적인 설계와 구현 방식이야말로 그 어떤 새로운 기술과 환경, 툴보다 더 실제 프로젝트를 성공시키는 데 중요한 요소임을 알고 있다.
스프링의 기술
IoC/DI
- 스프링의 가장 기본이 되는 기술이자 스프링의 핵심 개발 원칙이기도 함
DI의 활용 방법
- 핵심 기능의 변경 : DI의 가장 대표적인 적용 방법은 바로 의존 대상의 구현을 바꾸는 것
- 핵심기능의 동적인 변경 : 일반적인 DI를 이용한 변경 방법과 달리 동적으로 매번 다르게 변경할 수도 있음
- DI를 잘 활용하면 애플리케이션이 동작하는 중간에 그 의존 대상을 다이내믹하게 변경할 수 있다.
- 부가기능의 추가 : 데코레이터 패턴을 생각해보면 됨
- 인터페이스의 변경 : 클라이언트가 사용하는 인터페이스와 실제 오브젝트 사이에 인터페이스가 일치되지 않는 경우에도 DI 가 유용하다
- A가 C 오브젝트를 사용하려 한다고 할 때, A는 원래 B 인터페이스를 사용하도록 만들어져 있고 C는 B 인터페이스를 구현하지 않았다.
- 이때 B 인터페이스를 구현했으면서 내부에서 C를 호출해주는 기능을 가진 어댑터 오브젝트를 만들어서 A에 DI 해주면 됨
- A → B(C로 위임) → C
- 프록시
- 템플릿과 콜백 : DI의 특별한 적용 방법. 콜백을 템플릿에 주입하는 방식으로 동작하게 함
- 싱글톤과 오브젝트 스코프 : DI가 필요한 중요한 이유 중 한가지는 DI 할 오브젝트의 생명주기를 제어할 수 있다는 것. DI 대상 오브젝트를 컨테이너가 관리한다는 의미
- 테스트
AoP
객체지향 기술만으로 복잡해져 가는 애플리케이션의 요구조건과 기술적인 난해함을 모두 해결하는 데 한계가 있음
AoP는 이런 객체지향 기술의 한계와 단점을 극복하도록 도와주는 보조적인 프로그래밍 기술
PSA(Portable Service Abstraction)
- 환경과 세부 기술의 변화에 관계없이 일관된 방식으로 기술에 접근할 수 있게 해줌
- 스프링은 JavaEE를 기본 플랫폼으로 하는 자바 엔터프라이즈 개발에 주로 사용되기에 다양한 JavaEE 기술에 의존적일 수 밖에 없다.
- 특정 환경과 기술에 종속적이지 않다는 게 그런 기술을 사용하지 않는다는 뜻은 아니다. 다만 POJO 코드가 그런 기술에 직접 노출되어 만들어지지 않는다는 말이다. 이를 위해 스프링이 제공하는 대표적인 기술이 바로 일관성 있는 서비스 추상화 기술임