
전체 글
스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술 - ~ 섹션1. 웹 애플리케이션 이해
현재 인터넷은 대부분 HTTP로 통신한다. 앞에서 배웠던거. 웹서버는 이 클라이언트에서 온 HTTP 요청을 형식에 알맞게 응답해주는 것 뿐이다. 웹서버는 종류가 정적인 파일만 다루었던 그냥 웹 서버(nginx 등), 실제로 코드를 실행시켜서 매번 다른 결과를 반환해줄 수 있는 동적 웹 서버(Web Application Server)(스프링 MVC등)가 있다. 요즘은 둘 다 어느정도 할 줄 알아서 경계가 애매하긴 하다. 따로 두면 좋은점이, WAS는 코드를 실행하다보니 자주 죽는걸 방지겸 업무 분담해서 부담을 좀 줄일 수 있다. 그리고 각자가 필요한 부분만 확장시켜서 사용 가능. 아까 위에서 웹 서버는 HTTP 요청이 오면 알맞은 HTTP 응답을 보내는 것이라고 했는데, 요청 내용 POST /save이런 ..
HTTP 웹 기본 지식 - ~ 섹션8. 캐시와 조건부 요청
http 상태코드는, 1xx, 2xx, 3xx, 4xx, 5xx가 있는데 주 내용을 보자. 1xx는 요청이 수신되어 처리중이라는 코드인데 거의 안쓴다. 2xx은 성공 - 200 OK 거의 다 200 사용 - 201 Created 이 요청에 의해 뭔가 저장되었을 때 - 202 Accepted 요청이 접수되었으나 아직 완료되지 않았음 - 204 No Content 요청은 완료했지만 보낼 데이터가 없음. 임시저장 같을때에 가끔 쓰일 듯. 실전에선 거의 대부분 200, 201로 한다. 3xx은 똑같은 redirect인데 왜 많냐면, 공통적으로 Location 해더가 있으면 Location 위치로 자동 이동한다. - 300 Multiple Choices - 301 Moved Permanently - 302 Fou..
HTTP 웹 기본 지식 - ~ 섹션5. HTTP 메서드 활용
인터넷의 거의 대부분이 HTTP/1.1버전. 이후는 성능개선이라. HTTP/3가 UDP로 넘어간 이유는 TCP는 handshake같은것도 해서 그런것조차 성능 개선으로 업애려고 UDP가 뜨고 있다고 한다. 사실 거의 HTTP만 쓰니 이런 사실들은 몰라도 된다. HTTP도 stateful과 stateless로 만들 수 있는데, stateless로 하는것이 서버상 큰 이점이니 어떻게 해서든 stateful로 만들 생각을 해야 한다. 단점은 서버가 기억을 못하다보니 클라이언트에서 쿠키로 저장하든 한번에 필요한 정보들을 바리바리 싸고 가야 한다는 것. 그래서 무상태가 되면 자연스레 서버를 쉽게 수평 확장할 수 있다는 장점이 생긴다. 요청을 올때마다 다시 연결하고 끊고 하다보니 handshake 고정 손실이 있었..
스프링 기본 - 섹션9. 빈 스코프
빈 스코프라고는 하지만, 뭔가 뒤로 갈 수록 잘 안쓰이지만 이론적으로는 알아야 하는 내용들을 설명해주는 듯 하다. 사실상 쓰는건 request정도고 prototype 아주 가끔 쓰는 정도인듯. 그래서 request scope를 배우기 위한 과정 같음. 일단 기존의 싱글톤을 보자. 싱글톤은 지금까지 써왔던 것으로, 컨테이너가 생성되고 빈으로써 컨테이너에 들어가서 스프링이 종료되어 컨테이너가 없어질 때 까지 계속 남아 혼자 일을 한다. 그런데 프로토타입 스코프는 평소엔 생성되지 않다가, 요청이 들어오면 빈을 새로 만들어서 수행하고 종료됨. 만들어질 때 스프링 컨테이너가 빈을 생성하고, 의존관계 주입, 초기화 까지만 해주고 뒤로는 신경 안써서 종료할때인 @PreDestroy를 사용하지 못한다. 싱글톤 안에 프..
스프링 기본 - 섹션8. 빈 생명주기 콜백
일단 이게 뭐냐면, 스프링 빈의 라이플사이클은 스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> 사용 -> 소멸전 콜백 -> 스프링 종료 이다. 객체에서 생성자와 초기화를 분리하는게 좋은데, 생성은 메모리에 공간 확보해서 생성하는 책임이 있고, 초기화는 외부 커넥션 등 무거운 책임을 가진다. 그래서 객체 생성 부분과 초기화 부분을 나누는게 더 좋다고 한다. 그래서 밑에 예제 보면 생성하고 set은 나중에 함. 결론은 그냥 @PostConstruct, @PreDestroy 써라. 유일한 단점은 외부 라이브러리에는 적용하지 못한다고 해서 이럴땐 @Bean에서 초기화 함수, 소멸 함수 정하는거 쓰자. public class NetworkClient implements Ini..
스프링 기본 - 섹션7. 의존관계 자동 주입
앞에서 자동 의존 관계 주입 방법을 생성자를 통해 했는데, 사실 생성자 말고도 setter, 필드 주입, 일반 메서드 주입이 있다. 하지만 그나마 가끔 쓰는데 setter고 다른 방법들은 거의 안쓰니 생성자를 쓰자. new로 생성할 때 딱 한번 호출됨이 보장된다. @Component public class OrderServiceImpl implements OrderService { private final MemberRepository memberRepository; private final DiscountPolicy discountPolicy; @Autowired public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy disc..
스프링 기본 - 섹션6. 컴포넌트 스캔
@Autowired가 뭔지, 기존에 수동으로 만들었던 AppConfig를 어떻게 자동화 하는지 알아보는 내용이다. 이렇게 수동으로 등록한 것과 이렇게 자동으로 등록한 것은 같은 역할을 한다. 이게 뭐냐면 AutoAppConfig는 똑같이 @Configuration이지만 @ComponentScan을 통해 AutoAppConfig가 들어있는 패키지 이하(따로 설정 가능)를 모두 스캔해서 annotation @Component가 붙은 클래스를 컨테이너에 등록한다. 다만 이렇게 하면 수동으로 했을 때 DI를 지정해줬지만 AutoAppConfig안엔 아무것도 없으므로 해당 구체화 인스턴스 생성자에 @Autowired로 어떤걸 주입하는지 알려준다. 스캔 범위 설정은 속도를 높이기 위해 가끔 필요한 듯 하다. 그럼 ..
스프링 기본 - 섹션5. 싱글톤 컨테이너
일단 싱글톤은 다음과 같이 앱 전체에서 인스턴스 한번만 만들어두고 해당 객체를 불러올 때마다 미리 만들어둔 인스턴스를 가지고 오는 방식이다. 요청할 때마다 함수 실행하려도 새로 만들면서 사용하면 클라이언트가 매번 요청할 때마다 만들어야 하니 너무 비효율적이기 때문. 하지만 싱글톤의 문제점은 - 구현 코드가 너무 많이 들어간다. 저거 하나만 해도 생성자 막고, 불러오면 다시 같은거 반환해주고 하는 코드 일일히 만들어야 함 - 의존관계상 클라이언트가 구체 클래스에 의조한다 -> DIP 위반. 인터페이스에 의존해야 하는데 함수 실행을 위해 인스턴스를 만들고 그걸 의존해야 함 - 클라이언트가 구체 클래스에 의존해서 OCP 원칙을 위반할 가능성이 높다. - 테스트하기 어렵다. - 내부 속성을 변경하거나 초기화하기..
스프링 기본 - 섹션4. 스프링 컨테이너와 스프링 빈
앞의 섹션3 마지막에 @Bean으로 등록하면 스프링 실행 시 처음에 @Bean으로 등록된 모든 함수를 순회해서 등록한다고 했는데, 그 개념과 직접 확인하는 과정이다. 컨테이너에 이름을 키, 객체를 값으로 저장하고 ApplicationContext의 .getBean으로 가져와서 사용하는 것. 조회는 이름으로, 타입으로, 구체 타입으로 등 여러 방법으로 조회할 수 있다. 단지 타입으로 했을 시 겹치는게 있으면 에러 띄워서 중지하고 하는게 있음. 이런건 안겹치게 잘 하면 된다. 애초에 겹치면 이상하게 설계한거임. 상속 타입으로도 조회 가능 사실 지금까지 ApplicationContext로 가져온 것 또한 인터페이스로 가져온 것이었고, 스프링 컨테이너의 최상위 인터페이스는 BeanFectory. 여기에 Bean..
스프링 기본 - 섹션2,3. 스프링 핵심 원리 이해 - 예제 만들기, 객체 지향 원리 적용
일단 순수 자바로 만든 다음 왜 불편한지 확인 후 스프링을 도입하는 방식으로 진행한다고 한다. 중요하다고 생각한건 DIP를 지키기 위해 구현된 인스턴스가 아닌 인터페이스를 보고 구현한다는 점임. 물론 저렇게 Memory~~ 하면 클래스를 바꿀 때 저 이름도 바꿔야 해서 개방-폐쇄 원칙이 깨진다. 이런걸 수정하면서 스프링을 알아볼 예정. 인터페이스를 도입하게 됨으로써 나중에 새로운 기능이 구체적으로 정해지거나 바뀌어도 똑같은 인터페이스를 사용하기 때문에 상속하는 클래스를 만들고 인스턴스만 갈아끼우면 된다. 그래서 구체적으로 기능을 정하지 않았어도 일단 만드는게 가능하다. 위 코드를 보면 OrderServiceImpl 인스턴스가 다른 인터페이스만 보는게 아니고 인스턴스도 함께 보기 때문에 OCP 위반이다. ..