
-> Spring을 사용한다는건 Frame안에서 work를 한다고 할 수 있음
프레임워크가 미리 구성된 것을 가져와서 사용한다는 의미에서 API와도, 라이브러리와도 비슷한 느낌이 들어 셋의 정확한 개념을 알고 있는 것이 중요하다.
애플리케이션 프로그래밍 인터페이스의 약자로 interface라는 이름에서 알 수 있듯 2개 이상의 소프트웨어 컴포넌트 사이에서 상호작용 할 수 있도록 정의된 인터페이스를 의미함-> 즉, 소프트웨어 애플리케이션이 서로 데이터를 주고 받으며 통신할 수 있도록 만들어진 일련의 규칙이자 약속이라 할 수 있음.
-> 라이브러리의 제어권은 개발자에게 있음. 단순히 필요한 기능을 제공할 뿐임
-> 라이브러리의 제어권은 개발자에게 있음
-> but, 프레임워크의 제어권은 프레임워크에 있음
따라서, 개발자가 프레임워크가 정해둔 규칙과 구조에 맞게 코드를 작성하고 삽입하면, 실제 실행 흐름은 프레임워크가 관리함
이를 우리는 제어의 역전이라고 부름
즉, spring은 제어의 역전에 해당하는 프레임워크임
그렇다면 우리가 왜 제어의 역전에 대해 이해하고 있어야하는지 궁금할 것 같음
위에 계속 언급했듯, 프로그램의 제어 흐름을 개발자가 직접 제어하는 것이 아니라 외부에서 관리하는 것을 제어의 역전이라고 함
일반적인 프로그램을 작성할 때는 객체의 생성, 설정, 초기화, 메서드 호출, 소멸까지의 모든 과정을 개발자가 직접 제어해야 함.
-> 애플리케이션의 실행 흐름, 생명주기는 모두 전적으로 개발자가 관리하는 구조임
But, 프레임 워크를 사용하면 객체의 생명 주기를 모두 프레임 워크에 위임함.
제어의 역전에서는 오브젝트가 스스로 사용할 오브젝트를 결정하지도 생성하지도 않음
-> IoC가 제어권을 외부로 넘긴다면, 이를 실행하기 위해 DI를 사용함
DI는 객체가 필요로 하는 것(=종속성)을 직접 만들지 않고 외부에서 주입받는 방식을 의미함
토비의 스프링에서는 다음의 세 가지 조건을 충족하는 작업을 의존관계 주입이라고 말함.
1. 클래스 모델이나 코드에는 런타임 시점과 의존관계가 들어나지 않음. 즉, 인터페이스에만 의존하고 있어야 함.
2. 런타임 시점의 의존관게는 컨테이너나 팩토리와 같은 제 3의 존재가 결정함.
3. 의존관게는 사용할 오브젝트에 대한 래퍼런스를 외부에서 주입해주며 만들어짐.
여기서 객체를 생성하고 관리하며 의존관계를 연결해주는 컨테이너를 우리는 IoC 컨테이너 혹은 DI 컨테이너라고 부름
-> 객체가 생성자 인수, 메서드에 대한 팩토리 메서드에서 생성되거나 반환된 후에 객체 인스턴스에 설정된 속성을 통해서만 종속성을 정의하는 프로세스라고 보면 됨.
정리해보면,
1. 객체가 자기 안에서 필요한 것들을 직접 만들지 않고,
2. 생성자 인자, 메서드, 혹은 팩토리 메서드를 통해 외부에서 만들어진 것을 전달받아 사용함
3. 전달 받은 후에는 객체 안에서 설정된 속성을 통해서만 종속성을 사용함
개발 상황에서는 객체를 마주했을때 서로 의존되어있는 경우가 대다수임.
독립적으로 존재하는 객체도 존재할 수 있으나, 로직을 구현하면서 필연적으로 서로 의존성을 지닌 경우가 많을 것임
ex1) RegularCoffeeBean을 커피 원두로 사용 -> 원두 일체형
public static class RegularCoffeeBean{
public void grind() {
System.out.println("기본 원두로 갈고 있습니다");
}
}
public static class CoffeeMachine {
private RegularCoffeeBean regularCoffeeBean;
public CoffeeMachine() {
this.regularCoffeeBean = new RegularCoffeeBean();
}
public void brew() {
regularCoffeeBean.grind();
System.out.println("기본 원두로 커피를 내립니다.");
}
}
ex2) 원두 분리형
// 인터페이스
public interface CoffeeBeans {
void grind();
}
// 인터페이스 구현하는 구현체 클래스
@Component("regularBean")
public static class RegularCoffeeBeans implements CoffeeBeans {
@Override
public void grind() {
System.out.println("기본 원두로 갈고 있습니다");
}
}
// 원두 종류 바꾸고싶을땐? 구현체 클래스를 또 만들면 됨
@Component("decafBean")
public static class DecafCoffeeBeans implements CoffeeBeans {
@Override
public void grind() {
System.out.println("디카페인 원두로 갈고 있습니다");
}
}
// 커피머신
@Component
public static class CoffeeMachine {
@Autowired
@Qualifier("decafBean")
private CoffeeBeans coffeeBeans;
public void brew() {
coffeeBeans.grind();
System.out.println("원두로 커피를 내립니다.");
}
}
원두일체형은 강한 결합 원두분리형은 느슨한 결합이라고 할 수 있음
-> 각 객체끼리 의존성이 존재할 때 의존성을 외부에서 주입받는 것이 바람직 함.
기존의 서버는 정적인 자료만을 주고 받고 있었음.
웹이 다양한 기능을 요구하게 되면서 사용자의 요구에 맞춘 동적인 페이지를 만들 필요가 생김 -> 이를 위해 만들어진 것이 서블릿 !
1. WS (Web Server)
- 웹서버를 뜻하며 주로 정적인 컨텐츠 (HTML, img ..)를 클라이언트에 전달함
- 요청 -> 응답 (대부분 HTTP)
- 정적인 웹페이지 처리에 최적화
- 동적인 처리 (데이터 베이스 접근 불가)
- Apache HTTP Server, Nginx 존재
2. WAS (Web Application)
- WAS는 웹 애플리케이션 서버라고 부르며, 동적인 웹 서비스를 처리함
- 클라이언트 요청 -> 서버 측에서 로직 처리 -> 결과 응답
- DB 접근, 비즈니스 로직 실행 가능
- 주로 Servlet, JSP, Spring 등 동적인 웹 서비스 제공 가능
- Tomcat, JBoss, WebLogic, Spring Boot embedded Tomcat 존재


Servlet이 어떤 역할을 수행하는 메뉴얼이라면,
Servlet Container는 클라이언트의 요청을 받아주고 응답할 수 있게 웹 서버과 Socket으로 통신하며 직접 핸들링한다고 볼 수 있음.
클라이언트의 요청이 들어오면 ...
서블릿 컨테이너는 web.xml을 기반으로 사용자가 요청한 URL이 어느 서블릿에 대한 요청인지 찾음
그렇다면 web.xml은 무엇인가?
-> 웹 애플리케이션의 배치 파일로 서블릿, 필터, 리스너 등 웹 구성 요소의 설정 정보를 정의하는 환경설정 파일임
-> 여기서 정의된 서블릿과 URL 매핑 정보를 확인하고, 매핑된 서블릿이 있으면 해당 서블릿으로 전달하고, 서블릿이 처리한 응답을 브라우저로 보내줌.
본래 네트워크를 통한 소통을 위해서는 Socket을 만들고 listen(), accept(), connect()를 통해 구현해야함.
하지만 servlet 컨테이너는 이러한 기능을 api로 제공하여 간편화 함
-> 우리는 servlet으로 구현해야 할 비즈니스 로직에 대해서만 집중하면 되는 것임 !!!
빈은 Spring 컨테이너가 관리하는 자바의 객체를 의미함.
Spring은 Bean을 통해 객체를 인스턴스화한 후, 객체 간의 의존관계를 관리함.
객체가 의존관계를 등록할 때, Spring 컨테이너에서 해당하는 빈을 찾고, 그 빈과 의존성을 만들게 됨.
public class UMC9thMember {
private int age;
private String nickname;
private String school;
private String studyPart;
public UMC9thMember(){
}
public UMC9thMember(int age, String nickname, String school, String studayPart) {
this.age = age;
this.nickname = nickname;
this.school = school;
this.studyPart = studyPart;
}
}
// 여기서 객체를 생성하기 위해서는
// new 생성자 사용 -> 개발자가 전적으로 생명주기, 의존성 관리 진행
UMC9thMember umc9thMember = new UMC9thMember(23, "마크","상명대학교", "Server(SpringBoot)");
@Component → @Autowired : 묵시적 빈 정의
@Configuration → @Bean : 명시적 빈 정의