TIL - 0528

스프링

@RestController와 @Controller의 내부 동작 차이

  • @Controller : 선언한 컨트롤러는 뷰 이름을 리턴하고, 뷰 리졸버가 뷰를 찾아 응답하는 형태 : text/html

  • @RestController : @Controller 선언과 @ResponseBody 선언을 합쳐둔 어노테이션
    • @ResponseBody : Http response message body에 컨버팅된 리턴 데이터를 써서 응답함
    • 리턴 데이터가 MessageConverter를 거쳐 요청자의 요청 형태로 컨버팅(json, xml)하여 응답 메세지 바디에 입력해서 응답함
    • MessageConverter 라이브러리 : Jacson(json), Marshalling(xml)

  • @RestController 적용 코드
@RestController
@RequestMapping("/api/questions/{questionId}/answers")
public class ApiAnswerController {
    
    @PostMapping
    public Answer create(@PathVariable Long questionId, String contents, HttpSession session) {
        log.info("answer contents : {}", contents);
        Question question = questionRepo.findById(questionId).get();
        Answer answer = Answer.builder().user(HttpSessionUtils.getUserFromSession(session).get()).question(question).contents(contents).build();
        question.addAnswer();
        return answerRepo.save(answer);
    }
}

제어의 역전(IOC)과 스프링

  • 제어의 흐름이 뒤바뀐 것 : 일반적으로 자신이 사용할 것에 대해서 자기가 정하는데 그렇지않고 제어 권한을 다른 대상에 위임함
    • 프레임워크도 IOC가 적용됨 : 어플리케이션 코드가 프레임워크에 의해 사용됨(라이브러리는 반대 - 어플리케이션 코드에서 필요한 기능만 가져와서 사용하는 것)
    • IOC 대상과 그 대상을 제어를 하는 존재가 있음
  • 컨테이너에서 사용할 객체를 생성하고, 호출해야하는 메소드를 호출하고, 관리하고 제거까지 제어를 컨테이너에서 따로함
  • 스프링에서 제어역전 개념 구현 : 스프링 빈 - 스프링 컨테이너에 의해 생성되고 관계 부여되고 사용되기까지 함

스프링 컨테이너

  • 스프링 빈을 생성하고 관계 설정하고 사용까지 제어를 하는 컨테이너
  • (제어)역할에 초점을 맞춰서 부르는 이름이 빈 팩토리
  • 실제로 제어를 할 때 부가 설정 정보를 참고해서 제어를 하는데 총칭해서 어플리케이션 컨텍스트라고 함 : 역할(책임)을 담당하는데, 부가 설정 정보를 활용해서 책임을 다하는 것

Reference

JPA

JPA를 사용하지않으면 SQL 종속 개발을 하게 됨

  • 테이블에 맞춰 객체를 설계하게되고, 객체는 데이터를 나르는 역할 밖에 하지못함
  • 데이터베이스의 테이블 컬럼에 변동사항이 생겼을 때 코드 상으로는 나뉘어져있지만(캡슐화) 변동에 따라 SQL을 전부 변경해줘야하기때문에 종속된 개발을 하게됨(엔티티 클래스)

JPA 기술을 활용한 개발의 이점

  • 테이블 먼저 구성하고 개발하는 것이 아니라 도메인을 먼저 구상할 수 있음 : 도메인 주도 개발(model, 로직을 처리하는 역할)
    • 복잡한 로직을 쿼리로 처리하는게 아니라 도메인에서 처리하는 것을 인지하면서 개발할 수 있음 : 객체지향 개발
  • SQL을 직접 만들지않고, 객체.메소드 코드로 데이터베이스 기능 콜 할 수 있음

  • 객체와 RDBMS의 테이블 불일치를 해결해줌 : ORM, 단순히 SQL만 만들어주는 역할을 하는 것이 아니라 불일치에서 오는 싱크 작업을 대신해줌
    • 객체를 데이터베이스에 저장하려면 직렬화해야하고, 저장된 데이터를 찾아오기위해서는 역직렬화를 해야하는 것을 안해도 됨
    • 상속 관계를 그대로 사용하기위해서는 귀찮은 SQL 작업을 해줘야하는데, 직접 하지않아도 됨

JPA를 구현한 하이버네이트

  • JPA는 자바 진영의 ORM 표준이고, 표준을 구현한 여러 구현체가 있는데 이를 ORM 프레임워크라 함 : 자바는 인터페이스로 표준 콜을 만들어두고, 구현체는 각각 구현하도록 해서 개발자가 통일된 방법으로 구현할 수 있도록 함(객체지향의 장점을 그대로 살려서)

  • ORM 프레임워크에 따라 단순 SQL(CRUD)변환 작업만 해주거나 패러다임 불일치를 해결까지 해줌 : 하이버네이트는 패러다임 불일치까지 해결해줌

네트워크

데이터를 주고 받기 과정

  • 서버는 소켓을 먼저 만들고 접속 대기 상태(가능)
  • 클라이언트도 통신을 위해 소켓을 만들고, 해당 서버에 제어 정보(IP, 포트)와 접속을 확인할 수 있는 데이터를 헤더에 기록해서 보냄(패킷)
  • 서버에서도 같은 상태 데이터를 보내면 접속되었다는 것 : connect() 작업 완료
  • 웹의 경우 리퀘스트 메세지를 보내는데, 한번에 보내는게 아니라 데이터를 쪼개서 패킷으로 보냄
  • 하나의 패킷을 보내고, 패킷을 제대로 수신했는지 확인하는게 아니라 윈도우 제어 방식 즉, 수신 버퍼가 받을 수 있는 만큼을 계속해서 보냄(수신 버퍼가 수신할 수 있는 양은 수신 측에서 보냄 - 윈도우값) : write() - read()
  • 통신이 완료되면 보통 서버에서 연결 끊기 작업을 들어가는데, 서버에서 헤더의 FIN에 1을 기록해서 보내면 클라이언트에서도 접속 끊기 작업을 한다는 신호를 똑같이 보내고 일정 시간 후 소켓을 말소함 : 서버에서 데이터를 받자마자 바로 말소하지않는 이유는 바로 말소시켜버린 후 같은 포트번호를 할당받은 소켓이 우연히 생성되었을 때 해당 서버로 요청을 보냈는데, 서버는 이미 말소에 들어가고 있기때문에 바로 요청이 reject 되어버리기때문에