💡 Spring Framework 프로젝트 생성 & 초기 설정
사전 작업
JDK-11 설치
JAVA_HOME 시스템 환경변수 설정
IntelliJ IDEA 설치
프로젝트 생성
Lombok 설정
한글 깨질 때
help - Edit VM Options 이동
-Dfile.encoding=UTF-8
입력
Spring Framework의 특징
장점
- 효율적인 코드 작성 (무베이스 코드작성 < 기본베이스 코드작성)
- 정해진 규약에 따른 유지보수성↑
- POJO(Plan Old Java Object) 기반의 구성
- DI(Dependency Injection) 지원
- AOP(Aspect Oriented Programming, 관점지향 프로그래밍) 지원
- Java 언어를 사용함으로써 얻는 장점
단점
- 학습해야 할 것이 많음
- 유연한 개발이 어렵다
💡 POJO (Plain Old Java Object) 란?
자바로 생성되는 순수한 객체
내가 작성한 코드가 객체지향적인지에 대한 사고를 항상 하기
POJO 프로그래밍의 2가지 규칙
- 1. Java나 Java의 스펙(사양)에 정의된 것 이외에는 다른 기술이나 규약에 얽매이지 않아야 한다
ex) getter setter만 정의된 코드 = Java 언어 이외의 특정한 기술에 종속되지 않은 순수한 객체 - 2. 특정 환경에 종속적이지 않아야 한다
POJO 프로그래밍이 필요한 이유
- 특정 환경이나 기술에 종속적이지 않으면 재사용 가능하고, 확장 가능한 유연한 코드를 작성할 수 있다.
- 저수준 레벨의 기술과 환경에 종속적인 코드를 애플리케이션 코드에서 제거 함으로써 코드가 깔끔해진다.
- 코드가 깔끔해지기 때문에 디버깅하기도 상대적으로 쉽다.
- 특정 기술이나 환경에 종속적이지 않기 때문에 테스트 역시 단순해진다.
- 객체지향적인 설계를 제한없이 적용할 수 있다.(가장 중요한 이유)
💡 IoC (Inversion of Control)
1. 어플리케이션 흐름의 주도권을 Spring이 갖게 하는 것
2. 서버 컨테이너 기술, 디자인 패턴, 객체지향 설계 등에 적용
예시
main() 메소드가 없는 서블릿 컨테이너에서 클라이언트의 요청이 들어올때마다
컨테이너 내의 컨테이너 로직(service() 메소드)이 서블릿을 직접 실행시키기 때문에 main()이 불필요함
이 경우, 서블릿 컨테이너가 서블릿을 제어하고 있기 때문에 어플리케이션의 주도권은 서블릿 컨테이너에 있다
서블릿과 웹 어플리케이션 간의 IoC(제어의 역전) 개념이 적용된 것
그럼 스프링에는 이 IoC 개념이 어떻게 적용되어 있을까?
답은 DI (Dependency Injection) 의존성 주입이다.
💡 DI (Dependency Injection)
IoC의 개념을 구체화 시킨 것
- MenuController 클래스는 클라이언트의 요청을 받는 endpoint 역할
- MenuService 클래스는 전달받은 클라이언트의 요청을 처리하는 역할
- 컨트롤러는 메뉴판의 메뉴목록을 조회하기 위해 서비스의 기능인 getMenuList()를 사용함
- 이 예시는 의존관계는 성립되었지만 의존성 주입은 이루어지지 않음
- 위의 의존관계에 비교하면, 위는 MemberController에서 MenuService의 객체를 직접 생성한 반면,
- 이 예시는 MenuController 생성자로 MenuService의 객체를 전달 받고 있음
- 주입엔 메소드,gettet / setter 주입 등 여러 방법이 있지만 이렇게 생성자 주입을 통한걸 의존성 주입이라고 함
- 의존성 주입엔 왠만하면 생성자 주입으로만 하는걸 추천한다
왜 의존성 주입이 필요할까
- 현재 클래스 내부에서 외부 클래스의 객체를 생성하기 위해 new 연산자 를 쓸지 말지 여부 결정
- new를 이용해 객체 생성하면 객체지향 설계관점에서 문제 발생 가능성
- Reflection 기법을 이용해 Runtime시에 동적인 객체 생성도 가능
- Stub = 메소드가 호출되면 미리 준비된 데이터 응답, 고정된 데이터 = 멱등성 (idempotent)
new 연산자를 사용하여 객체 전달을 할 경우, 참조할 클래스 변경시 사용하는 모든 클래스를 변경해야함
- 컨트롤러에 private MenuServiceStub menuService; 추가
- CafeClient에 MenuServiceStub menuService = new MenuServiceStub(): 추가
- MenuService를 MenuServiceStub으로 변경
- ↑ 위와 같이 할 시 모든 클래스를 일일이 변경해야하며, 강한 결합이라고도 부름
- 결론적으로 의존성 주입을 하더라도 느슨합 결합을 하여 변동사항에 동적으로 대처할 수 있어야함
느슨한 의존성 주입 방법 = 인터페이스 사용
- 컨트롤러가 서비스를 직접적으로 의존하는게 아닌 인터페이스에 의존한 상태
- 컨트롤러는 서비스에 의존하지만 서비스의 구현체가 무엇인지 알 수 없고, 알 필요도 없다
- 왜냐면 컨트롤러 입장에선 메뉴 목록 데이터를 조회할 수 만 있으면 되니까
- 즉, 어떤 클래스가 인터페이스 같이 일반화된 구성요소에 의존할때, 느슨한 결합 이라고 불림
- 인터페이스 타입의 변수에 인터페이스의 구현 객체를 할당 하면 업캐스팅이라고 함
핵심 포인트
- 애플리케이션 흐름의 주도권이 사용자에게 있지 않고, Framework이나 서블릿 컨테이너 등 외부에 있는 것 즉, 흐름의 주도권이 뒤바뀐 것을 IoC(Inversion of Control)라고 한다.
- DI(Dependency Injection)는 IoC 개념을 조금 구체화 시킨 것으로 객체 간의 관계를 느슨하게 해준다.
- 클래스 내부에서 다른 클래스의 객체를 생성하게 되면 두 클래스 간에 의존 관계가 성립하게 된다.
- 클래스 내부에서 new를 사용해 참조할 클래스의 객체를 직접 생성하지 않고, 생성자 등을 통해 외부에서 다른 클래스의 객체를 전달 받고 있다면 의존성 주입이 이루어 지고 있는 것이다.
- new 키워드를 사용하여 객체를 생성할 때, 클래스 간에 강하게 결합(Tight Coupling)되어 있다고 한다.
- 어떤 클래스가 인터페이스 같이 일반화 된 구성 요소에 의존하고 있을 때, 클래스들 간에 느슨하게 결합(Loose Coupling)되어 있다고 한다.
- 객체들 간의 느슨한 결합은 요구 사항의 변경에 유연하게 대처할 수 있도록 해준다.
- 의존성 주입(DI)은 클래스들 간의 강한 결합을 느슨한 결합으로 만들어준다.
- Spring에서는 애플리케이션 코드에서 이루어지는 의존성 주입(DI)을 Spring에서 대신 해준다.
- 객체 지향 설계 원칙에서 DI와 관련된 설계 원칙을 찾아보자.
- SOLID(객체 지향 설계 원칙): https://ko.wikipedia.org/wiki/SOLID(객체지향_설계)
- SOLID 요약: https://itvillage.tistory.com/entry/객체지향-설계-원칙-SOLID-원칙
💡 AOP (Aspect Oriented Programming) 란?
어플리케이션에 필요한 기능 중 공통적으로 적용되는 공통 기능에 대한 관심과 관련됨
공통관심사항
어플리케이션 전반에 걸쳐 공통으로 사용되는 기능들
핵심관심사항
어플리케이션의 주 목적을 달성하기 위한 핵심 로직에 대한 관심사
커피 주문 어플리케이션 예시
핵심관심사항 = 메뉴등록,주문기능
공통관심사항 = 어플리케이션 보안
AOP가 필요한 이유
- 코드의 간결성
- 객체 지향 설계 원칙에 맞는 코드 구현
- 코드의 재사용성
핵심 포인트
- AOP(Aspect Oriented Programming)는 관심 지향 프로그래밍이다.
- AOP에서 의미하는 Aspect는 애플리케이션의 공통 관심사를 의미한다.
- 애플리케이션의 공통 관심사는 비즈니스 로직을 제외한 애플리케이션 전반에 걸쳐서 사용되는 공통 기능들을 의미한다.
- 애플리케이션 전반에 걸쳐서 사용되는 공통 기능에는 로깅, 보안, 트랜잭션, 모니터링, 트레이싱 등의 기능이 있다.
- AOP를 애플리케이션에 적용해서 다음과 같은 이점을 누릴 수 있다.
- 코드의 간결성 유지
- 객체 지향 설계 원칙에 맞는 코드 구현
- 코드의 재사용
- AOP로 적용 할만한 공통 기능에는 뭐가 있을지 생각
💡 PSA (Portable Service Abstraction) 이란?
클라이언트가 추상화된 상위 클래스를 일관되게 바라보며 하위 클래스의 기능을 사용하는 것
↑ 일관된 서비스 추상화 (PSA)의 기본 개념
기능 접근방식을 일관되게 유지하면서 기술 자체를 유연하게 사용하는 것
아이의 특징을 추상화한 코드 예시
public abstract class Child {
protected String childType;
protected double height;
protected double weight;
protected String bloodType;
protected int age;
protected abstract void smile();
protected abstract void cry();
protected abstract void sleep();
protected abstract void eat();
}
핵심 포인트
- 객체지향 프로그래밍 세계에서 어떤 클래스의 본질적인 특성만을 추출해서 일반화 하는것을 추상화(Abstraction)라고 한다.
- 클라이언트가 추상화 된 상위 클래스를 일관되게 바라보며 하위 클래스의 기능을 사용하는 것이 바로 일관된 서비스 추상화(PSA)의 기본 개념이다.
- 애플리케이션에서 특정 서비스를 이용할 때, 서비스의 기능을 접근하는 방식 자체를 일관되게 유지하면서 기술 자체를 유연하게 사용할 수 있도록 하는 것을 PSA(일관된 서비스 추상화)라고 한다.
- PSA가 필요한 주된 이유는 어떤 서비스를 이용하기 위한 접근 방식을 일관된 방식으로 유지함으로써 애플리케이션에서 사용하는 기술이 변경되더라도 최소한의 변경만으로 변경된 요구 사항을 반영하기 위함이다.
💡 Spring Boot 사용 이유
- XML 기반의 복잡한 설계 방식 지양
- 의존 라이브러리의 자동 관리
- 애플리케이션 설정의 자동 구성
- 프로덕션급 애플리케이션의 손쉬운 빌드
- 내장된 WAS를 통한 손쉬운 배포
💡 More
Java 서블릿(Servlet)이란?
- Java Servlet 자체를 사용하는 기술은 현재 거의 사용하고 있지 않지만 Servlet은 Spring MVC 같은 Java 기반의 웹 애플리케이션 내부에서 여전히 사용이 되고 있음.
- Servlet에 대해서 더 알고 싶다면 아래 링크를 클릭
서블릿 컨테이너(Servlet Container)란?
- 서블릿 컨테이너(Servlet Container)는 서블릿(Servlet) 기반의 웹 애플리케이션을 실행해주는 것부터 시작해서 Servlet의 생명 주기를 관리하며, 쓰레드 풀(Thread Pool)을 생성해서 Servlet과 Thread를 매핑 시켜주기도 함
- 서블릿 컨테이너에 대한 자세한 내용이 궁금하다면 아래 링크를 클릭
- 서블릿 컨테이너: https://ko.wikipedia.org/wiki/웹_컨테이너
- 아파치 톰캣(Apache Tomcat)은 서블릿 컨테이너의 한 종류로써 Spring MVC 기반의 웹 애플리케이션 역시 기본적으로 아파치 톰캣에서 실행이 됨.
- 아파치 톰캣에 대한 내용은 아래 링크에서 확인
- 객체 지향 설계 원칙
- 객체지향 설계 원칙에 대해 학습을 하고 싶다면 아래 링크를 클릭.
- SOLID(객체 지향 설계 원칙): https://ko.wikipedia.org/wiki/SOLID(객체지향_설계)
- SOLID 요약: https://itvillage.tistory.com/entry/객체지향-설계-원칙-SOLID-원칙
- 객체지향 설계 원칙에 대해 학습을 하고 싶다면 아래 링크를 클릭.
'Framework > Spring' 카테고리의 다른 글
DTO (Data Transfer Object) (0) | 2022.10.21 |
---|---|
Spring MVC & Rest API URI 작성 규칙 (0) | 2022.10.20 |
AOP & JoinPoint & PointCut (0) | 2022.10.17 |
Component Scan, Container 설정 (0) | 2022.10.14 |
Spring Container & Bean & Singleton (0) | 2022.10.13 |