자바 엔터프라이즈 기술의 혼란 속에서 잃어버렸던 객체지향 기술의 진정한 가치를 회복시키고, 그로부터 객체지향 프로그래밍이 제공하는 폭 넓은 혜택을 누릴 수 있도록 기본으로 돌아가자는 것이 바로 스프링의 핵심 철학이다.
2️⃣스프링을 이해하려면 오브젝트에 깊은 관심을 가져야 한다.
스프링이 가장 관심을 많이 두는 대상은 오브젝트다.
애플리케이션에서 오브젝트가 생성되고 다른 오브젝트와 관계를 맺고, 사용되고, 소멸하기까지의 전 과정을 진지하게 생각해볼 필요가 있다. 더 나아가서 오브젝트는 어떻게 설계돼야 하는지, 어떤 단위로 만들어지며 어떤 과정을 통해 자신의 존재를 드러내고 등장해야 하는지에 대해서도 살펴봐야 한다.
3️⃣오브젝트에 대한 관심 ➡ 오브젝트 설계
객체지향 설계(Object Oriented Design)의 기초와 원칙
다양한 목적을 위해 재활용 가능한 설계 방법인 디자인 패턴
좀 더 깔끔한 구조가 되도록 지속적으로 개선해나가는 작업인 리팩토링
오브젝트가 기대한 대로 동작하고 있는지를 효과적으로 검증하는 데 쓰이는 단위 테스트
3️⃣스프링은 객체지향 설계, 구현을 강요하지 않는다.
하지만 오브젝트를 어떻게 효과적으로 설계하고 구현, 사용, 이를 개선해나갈 것인가에 대한 명쾌한 기준 마련
객체지향 기술과 설계, 구현에 관한 실용적인 전략과 검증된 베스트 프랙티스를 평범한 개발자도 자연스럽고 손쉽게 적용할 수 있도록 프레임워크 형태로 제공한다.
스프링의 핵심 가치를 이해하고, 스프링 스스로가 그 가치를 어떻게 적용해서 만들어져 있는지 이해한다.
스프링에는 가장 중요한 핵심 가치와 그것이 가능하도록 도와주는 세 가지 핵심 기술이 있다.
IoC / DI - 오브젝트의 생명주기와 의존관계에 대한 프로그래밍 모델. - 객체지향 설계 원칙과 디자인 패턴의 핵심 원리를 담고 있으며 프레임워크의 근간으로 삼고 있다. - 스프링이 직접 제공하는 모든 기술과 API, 심지어 컨테이너도 IoC/DI 방식으로 작성되어 있다.
서비스 추상화 - 이식성이 뛰어나다(서버, 특정 기술에 종속 되지 않는다.)
AOP - 애플리케이션 코드에 산재해서 나타나는 부가적인 기능을 독립적으로 모듈화 하는 프로그래밍 모델
2️⃣ 스프링의 기술에 대한 지식과 선택 기준 정립
스프링의 본 원리를 확실하게 이해 후 이를 다양한 방법으로 확장하고 적용했는지 살펴볼 차례이다.
스프링은 매우 범용적이고 애플리케이션의 모든 레이어를 폭 넓게 다루고 있다. => 그 중에서 어떤 것을 선택할지는 개발자의 몫이다.
스프링이 제공하는 방법과 연동하는 프레임워크와 스타일을 사용할 것인지는 개발자에게 큰 고민이다. => 이런 고민을 피하고 남들이 만들어놓은 예제를 가져다가 생각없이 사용하는 일은 피해야 한다.
두 번째 단계는 바로 이 다양한 선택의 문제를 각 기술영역별로 효과적으로 다루는 법을 배우는 것이다. => 먼저 스프링이 제공하는 기술의 종류와 접근 방법에는 어떤 것이 있는지 충분히 살펴보고, 선택의 기준을 마련해서 그때그때 상황에 맞는 최선의 기술과 접근 방법을 선택 할 수 있어야 한다.
3️⃣ 스프링의 적용과 확장
스프링의 다양한 기술을 어떻게 실제 애플리케이션 개발에 어떤 식으로 적용해야 하는지를 공부해야 한다. => 스프링은 특정 아키텍처에 제한되는 프레임워크가 아니다.
스프링은 이전에는 기술적인 문제로 쉽게 적용하지 못했던 아키텍처도 마음껏 활용할 수 있게 도와준다. => 또한 스프링에 제공하는 기능을 그대로 사용하는 것 외에도 그것을 확장하거나 추상화해서 사용하는 방법을 알아야 한다. * 스프링을 효과적으로 사용하는 기업과 개발팀에서는 스프링을 기반으로 프레임워크를 만들어서 사용한다.
스프링을 효과적으로 사용할 수 있도록 주어진 환경과 현재 프로젝트에 맞는 방식의 사용 기준을 마련하고, 이를 틀(프레임워크)의 형태로 만들어서 개발자들이 이용할 수 있게 해주는 것이다. 스프링의 자유도를 줄이고 각 현장의 상황에 맞는 접근 방법을 정립해주는 작업이라고도 볼 수 있다. 때로는 스프링이 직접 지원 하지 않는 기술을 접목해서 사용하는 경우를 위해서 해당 기술을 스프링에 맞게 통합하는 작업도 포함된다.
애플리케이션 개발을 빠르고 효율적으로 할 수 있도록 애플리케이션의 바탕이 되는 틀과 공통 프로그래밍 모델, 기술 API 등을 제공해준다.
1️⃣ 애플리케이션의 기본 틀 - 스프링 컨테이너
스프링은 스프링 컨테이너 또는 애플리케이션 컨텍스트라고 불리는 스프링 런타임 엔진을 제공한다. - 스프링 컨테이너는 설정정보를 참고로 해서 애플리케이션을 구성하는 오브젝트를 생성 및 관리 - 스프링 컨테이너는 독립적으로 동작할 수도 있지만 보통 웹 모듈에서 동작하는 서비스나 서블릿으로 등록해서 사용
* 스프링을 사용하려면 먼저 스프링 컨테이너를 다루는 방법과 스프링 컨테이너가 애플리케이션 오브젝트를 이용할 수 있도록 설정정보를 작성하는 방법을 알아야 한다.
2️⃣ 공통 프로그래밍 모델 - IoC/DI, 서비스 추상화, AOP
프로그래밍 모델이란?
프레임워크가 애플리케이션을 구성하는 오브젝트가 생성되고 동작하는 방식에 대한 틀을 제공해주고, 애플리케이션 코드가 어떻게 작성돼야 하는지에 대한 기준을 제시해준다.
이런 틀을 프로그래밍 모델이라고 한다.
스프링이 제공하는 핵심 세 가지 프로그래밍 모델
IoC/DI - 오브젝트의 생명주기와 의존관계에 대한 프로그래밍 모델 - 스프링은 유연하고 확장성이 뛰어난 코드를 만들 수 있게 도와주는 객체지향 설계 원칙과 디자인 패턴의 핵심 원리를 담고 있는 IoC / DI를 프레임워크의 근간으로 삼고 있다. - IoC / DI 방식을 따라서 작성돼야 스프링이 제공하는 가치를 제대로 누릴 수 있다. - 스프링이 직접 제공하는 모든 기술과 API, 심지어 컨테이너도 IoC / DI 방식으로 작성되어 있다. 스프링을 바르게 이해하고 효율적으로 사용하는 데 기본이 되며 가장 중요한 기술이다.
서비스 추상화 - 스프링이 사용하면 환경이나 서버, 특정 기술에 종속되지 않고 이식성이 뛰어나며 유연한 애플리케이션을 만들 수 있는데, 이를 가능하게 해주는 것이 바로 서비스 추상화다. - 구체적인 기술과 환경에 종속되지 않도록 유연한 추상 계층을 두는 방법이다.
AOP - 애플리케이션 코드에 산재해서 나타나는 부가적인 기능을 독립적으로 모듈화하는 프로그래밍 모델이다. - 스프링은 AOP를 이용해서, 다양한 엔터프라이즈 서비스를 적용하고도 깔끔한 코드를 유지할 수 있게 해준다.|
3️⃣ 기술 API
스프링은 엔터프라이즈 애플리케이션 개발의 다양한 역영에 바로 활용할 수 있는 방대한 양의 기술 API를 제공한다. - UI 작성은 물론이고 웹 프레젠테이션 계층, 비즈니스 서비스 계층, 기반 서비스 계층, 도메인 계층, 데이터 액세스 계층 등에서 필요한 주요 기술을 스프링에서 일관된 방식으로 사용할 수 있도록 지원해주는 기능과 전략 클래스 등을 제공한다.
스프링이 제공하는 API와 지원 기술은 모두 스프링의 프로그래밍 모델에 따라 작성되어 있기 때문에, 이를 가져다 쓰는 것만으로도 스프링의 프로그래밍 모델을 코드에 자연스럽게 적용 할 수 있다.
스프링의 모든 기술은 표준 자바 엔터프라이즈 플랫폼 (JavaEE)에 기반을 두고 있다. => 표준 기술과 더불어 유명 오픈소스 기술과 주요 상용 기술에 대한 지원 기능도 다양하게 제공된다.
스프링을 사용한다는 것은 이 세 가지 요소를 적극적을 활용해서 애플리케이션을 개발한다는 뜻이다.
클래스는 스프링 컨테이너 위에서 오브젝트로 만들어져 동작하게 만든다.
코드는 스프링의 프로그래밍 모델을 따라서 작성한다.
엔터프라이즈 기술을 사용할 때는 스프링이 제공하는 기술 API와 서비스를 활용하도록 한다.
추상클래스처럼 추상메서드를 갖지만 추상클래스보다 추상화 정도가 높다. => 추상클래스와 달리 몸통을 갖춘 일반 메서드 또는 멤버변수를 구성원으로 가질 수 없다. 오직 추상메서드와 상수만을 멤버로 가질 수 있다.
인터페이스는 구현된 것은 아무것도 없고 밑그림만 그려진 '기본 설계도'
interface 인터페이스이름 { public static final 타입 상수이름 = 값; public abstract 메서드이름(매개변수목록); }
인터페이스 멤버들의 제약사항
모든 멤버변수는 public static final ,이어야 하며, 이를 생략할 수 있다.
모든 메서드는 public abstract 이어야 하며, 이를 생략할 수 있다. => 단, static 메서드와 디폴트 메서드는 예외(JDK1.8부터)
interface PlayingCard { public static final int SPADE = 4; final int DIAMOND = 3; // public static final int DIAMOND = 3; static int HEART = 2; // public static final int HEART = 2; int CLOVER = 1; // public static final int CLOVER = 1;
public abstract String getCardNumber(); String getCardKind(); // public abstract String getCardKind(); }
인터페이스에 정의된 모든 멤버에 예외없이 적용되는 사항이기 때문에 제어자를 생략할 수 있는 것이며, 편의상 생략하는 경우가 많다. 생략된 제어자는 컴파일 시에 컴파일러가 자동적으로 추가해준다.
# 인터페이스 구현
인터페이스도 추상클래스처럼 그 자체로는 인스턴스를 생성할 수 없다.
인터페이스는 자신에 정의된 추상메서드의 몸통을 만들어주는 클래스를 작성해야 한다.
추상클래스는 확장한다는 의미의 키워드 'extends', 인터페이스는 구현한다는 의미의 키워드 'implements'
인터페이스의 이름은 주로 Fightable과 같이 '~ 을 할 수 있는'의 의미인 able로 끝나는 경우가 많다.
class 클래스이름 implements 인터페이스이름 { // 인터페이스에 정의된 추상메서드를 구현해야 한다. }
class Fighter implements Fightable { public void move(int x, int y) { /* 내용 생략 */ } public void attack(Unit u) { /* 내용 생략 */ } }
# 인터페이스의 장점
개발시간을 단축시킬 수 있다.
표준화가 가능하다.
서로 관계없는 클래스들에게 관계를 맺어 줄 수 있다.
독립적인 프로그래밍이 가능하다. - 클래스의 선언과 구현을 분리시킬 수 있기 때문에 실제구현에 독립적인 프로그램을 작성하는 것이 가능하다.