Skip to content

스프링 핵심 원리 ‐ 기본편 : 섹션7 ~ 섹션 9

minahkim03 edited this page May 14, 2024 · 4 revisions

섹션 7: 의존관계 자동 주입

  • 생성자 주입: 생성자 호출시점에 딱 한번만 호출되는 것이 보장 -> 불변, 필수 의존관계에 사용, 빈을 생성할 때 의존관계도 자동 주입

  • 수정자 주입: @Autowired 밑에 setter를 이용해 의존관계 주입 -> 선택, 변경이 있는 의존관계에 사용, 빈 생성 후 의존관계 주입

  • 필드 주입: 필드에 바로 선언 -> 코드를 수정하려면 setter를 따로 만들어야하기 때문에 불편 -> 추천하지 않음.

  • 일반 메서드 주입: 생성자 주입과 비슷하게 한번에 여러 필드 주입 -> 일반적으로 잘 사용하지 않음. -> 불변, 누락을 방지하고 final 키워드를 사용할 수 있기 때문에 항상 생성자 주입을 선택하는 것이 좋음.

  • @Autowired 옵션 설정 @Autowired(required = false): 자동 주입 대상이 없으면 생성자가 호출이 되지 않음. @Autowired public void setNoBean2(@Nullable Member noBean2){}: 자동 주입 대상이 없으면 null이 주입됨. @Autowired public void setNoBean3(Optional<Member> noBean3){}: 자동 주입 대상이 없으면 Optional.empty가 주입됨.

  • Lombok:Getter, Setter를 편리하게 만들어주고 @RequiredArgsConstructor를 사용하며 final 키워드가 붙은 필드를 모아 생성자를 만들어줌.

  • @Autowired 필드명 매칭: 타입 매칭의 결과가 2개 이상이면 필드명, 파라미터 명으로 빈 이름 매칭해야함.

  • @Qualifier 사용: 빈에 별칭을 붙여서 파라미터에 이를 명시함. 해당 Qualifier를 가진 빈을 찾지 못하면 똑같은 이름의 빈을 찾음 -> NoSuchBeanDeifinitionException -> 애노테이션을 직접 만들어 사용(오타 등으로 인한 에러 방지)

  • @Primary 사용: @Primary로 우선순위를 지정 -> 여러 빈이 조회됐을 때에 @Primary를 가져옴

  • 타입이 같은 여러 빈을 모두 가지고 오려면 -> map, list 사용

섹션 8: 빈 생명주기 콜백

  • 스프링 빈의 라이프 사이클: 스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> 소멸전 콜백 -> 스프링 종료

  • 초기화, 소멸 인터페이스: implements InitializingBean, DisposableBean 선언 후 afterPropertiesSet()가 초기화 콜백, destroy()가 소멸전 콜백 -> 단점: 스프링 의존도가 높고 외부 라이브러리에 적용할 수 없다. -> 거의 사용하지 않음.

  • 빈 등록 초기화 메서드: @Bean(initMethod = "초기화 콜백 명", destroyMethod = "소면전 콜백 명")

  • 애노테이션: @PostConstruct 초기화 콜백, @PreDestroy 소멸전 콜백, 자바 표준 등등의 장점이 많으므로 이걸 사용하기를 권장.

섹션 9: 빈 스코프

  • 싱글톤: 스프링 컨테이너의 시작부터 종료까지 유지되는 기본 스코프.

  • 프로토타입: 프로토타입 빈의 생성과 의존관계 주입까지만 관리. 빈을 조회하면 항상 새로운 인스턴스를 생성하고 의존관계를 주입해서 반환함(관리 x->종료 메서드도 직접 호출해야함). -> 싱글톤 빈은 스프링 컨테이너 생성 때 빈이 생성, 초기화 되고 프로토타입 빈은 스프링 컨테이너에서 조회할 때 생성, 초기화 된다.

  • 싱글톤 빈 안에 의존관계로 프로토타입 빈이 주입되어 있을 경우 싱글톤 빈 생성 시에 프로토타입 빈이 주입되기 때문에 프로토타입 빈을 조회하면 새로운 인스턴스가 생성되지 않고 같은 빈이 조회됨. -> ObjectProvider를 사용해서 해결할 수 있음. @Autowired private ObjectProvider<PrototypeBean> prototypeBeanProvider; 선언 후 .getObject()로 새로운 프로토타입 빈을 받을 수 있음(Dependency Lookup,DL). 스프링에 의존한다는 단점 존재

  • JSR-330 Provider: 자바 표준이므로 다른 컨테이너에서도 사용 가능. @Autowired private ObjectProvider<PrototypeBean> prototypeBeanProvider; 선언 후 .get()로 새로운 프로토타입 빈을 받을 수 있음.

  • 웹 스코프: 웹 환경에서만 동작하고 스프링이 해당 스코프의 종료시점까지 관리함.

  • request: HTTP요청 하나가 들어오고 나갈 때 까지 유지되는 스코프.

  • session: HTTP Session과 동일한 생명주기를 가지는 스코프

  • application: 서블릿 컨텍스트와 동일한 생명주기를 가지는 스코프

  • web socket: 웹 소켓과 동일한 생명주기를 가지는 스코프

  • request 스코프는 고객 요청이 들어올 때만 유지되기에 스프링 컨테이너 생성 시에 존재하지 않음 -> ObjectProvider 사용

  • 프록시: ObjectProvider를 사용하지 않고 request 스코프에 가짜 프록시 객체 주입. -> ObjectProvider와 프록시의 공통점: 객체 조회를 필요한 시점까지 지연처리시킴.