Spring 32

컨트롤러 테스트 코드 작성 방법

컨트롤러는 클라이언트의 요청을 받아 필요한 자원을 응답해주는 API이다.  우리가 컨트롤러 코드를 작성하고 나서 제대로 동작하는지 확인하기 위해서는 POSTMAN 과 같이 요청을 보내는 프로그램을 통해서 직접 요청을 보내고 , 응답이 잘 오는지 확인해봐야한다. 그런데 요청을 받기 위해서는 서버가 동작중 이어야 하므로 매번 서버를  띄우고 직접 주소로 요청을 보내는 방식으로 테스트를 하려니 너무 번거로웠다.  그래서 테스트 코드가 필요한것이다. 테스트 코드를 작성해두면 굳이 서버를 직접 띄우지 않고, 직접 요청을 하지 않더라도 내가 만든 API가 제대로 동작하는지 점검할 수 있다.  먼저 컨트롤러 API가 제대로 동작하는지 확인 할 수 있는 테스트 코드 짜는 방법을 알아보자.  그런데 서비스 클래스는 로직..

[섹션 7-6] @Autowired 필드 명, @Qualifier, @Primary

지난 글에서 @Autowired를 사용할 때 같은 타입으로 조회되는 빈이 2개인 경우 오류가 발생했었다. @Autowired 로 빈을 자동으로 주입할 때, 특정한 빈을 지정해주는 방법이 무엇인지 알아보자 조회 대상 빈이 2개 이상일 때 해결 방법은 크게 3가지가 있다. @Autowired 필드 명 매칭 @Qualifier → @Qualifier끼리 매칭 → 빈 이름 매칭 @Primary 사용 1. @Autowired 필드명 매칭 : @Autowired 는 먼저 타입으로 빈을 찾고, 찾은 빈이 여러개라면 필드 이름, 파라미터 이름으로 빈 이름을 추가 매칭한다. 기존코드 @Autowired private final DiscountPolicy discountPolicy; 필드명을 빈 이름으로 변경 @Autow..

[섹션 7-5] @Autowired와 조회할 빈이 2개 이상인 경우

@Autowired는 타입으로 빈을 조회한다. @Autowired private DiscountPolicy discountPolicy 타입으로 빈을 조회하기 때문에 마치 다음과 유사하게 동작한다 ( 실제로는 더 많은 기능이 있다 ) ac.getBean(DiscountPolicy.class) 그런데, 빈 조회에서 공부했듯이 같은 타입의 빈이 2개이상 조회되는 경우 문제가 발생한다. DiscountPolicy는 RateDiscountPolicy 와 FixDisCountPolicy 라는 두 개의 구체화 클래스가 있었다. 이전에는 컴포넌트 스캔의 대상으로 RateDiscountPolicy 만 등록해줬지만, FixDisCountPolicy에 @Component를 추가해서 컴포넌트 스캔의 대상으로 만들어주자. 그리..

[섹션 7-4] 롬복과 최신 트렌드

의존 관계 주입을 자동으로 해줄 때 생성자 주입이 좋긴 하지만 코드가 많다... 생성자의 값을 설정해주는 코드를 넣어줘야하므로! 필드 주입의 경우 필드에 어노테이션 하나만 붙이면 끝인데.... 생성자 주입을 필드 주입처럼 편리하게 사용하는 방법이 없을까? ▶ 롬복을 이용하자 롬복 라이브러리 적용 방법 build.gradle에 코드 추가하기 //lombok 설정 추가 시작 configurations { compileOnly { extendsFrom annotationProcessor } } //lombok 설정 추가 끝 dependencies { implementation 'org.springframework.boot:spring-boot-starter' //lombok 라이브러리 추가 시작 compile..

[섹션 7-3] 생성자 주입을 선택해라!!

의존관계를 주입하는 방식은 크게 4가지나 있는데 왜 생성자 주입을 쓰라고 하는 걸까? 생성자 주입이 어떤 점에서 좋은지 자세히 알아보자. 생성자 주입 방식의 장점 먼저 OrderserviceImpl을 수정자 주입 방식으로 만들어보자. OrderServiceImpl @Component public class OrderServiceImpl implements OrderService{ private MemberRepository memberRepository; private DiscountPolicy discountPolicy; @Autowired public void setMemberRepository (MemberRepository memberRepository){ this.memberRepository=..

[섹션 7-2] 자동 주입 객체 옵션 처리

주입할 스프링 빈이 없어도 동작해야할 때가 있다. 예를 들어 주입 받을 객체가 세개인데 하나의 값은 주입 받지 못하더라도 메서드는 실행될 수 있도록 하고자 할 때가 있다. 그런데 @Autowired를 사용하면 기본값이 required의 값이 true로 설정되어있기 때문에 값이 없으면 오류가 발생한다. 자동 주입 대상을 옵션으로 처리하는 방법은 3가지가 있다. @Autowired(required=false) @Nuallable Optional 테스트 코드를 통해서 위의 옵션들에 따라 어떻게 동작하는지 알아보자 public class AutowiredTest { @Test void autowiredTest() { ApplicationContext ac = new AnnotationConfigApplic..

[섹션 7-1] 다양한 의존관계 주입 방법

의존관계 주입은 크게 4가지 방법이 있다. 생성자 주입 수정자 주입(setter 주입) 필드 주입 일반 메서드 주입 1. 생성자 주입 생성자 주입이란 생성자를 통해 의존관계를 주입받는 방법이다. 지금까지 이용한 방식이 생성자 주입 방식이다. 컴포넌트 스캔을 통해 빈을 등록할 때 @Autowired 어노테이션을 통해 스프링 컨테이너에서 의존 관계에 있는 객체를 자동으로 주입 시켜준다. 생성자 주입은 불변,필수 의존관계에 사용함 생성자 호출시 딱 1번만 호출되는것이 보장된다. 불변: 한번 호출해서 관계를 주입해주면 값이 바뀌지 않으므로 '불변'이다. 필수: private final .... 로 설정 -> 무조건 값이 있어야함 생성자가 하나일때는 @Autowired를 생략해도 된다. 하지만 생성자가 두개라면 ..

[섹션6-4] 중복 등록과 충돌

컴포넌트 스캔을 하는데 같은 이름의 빈을 등록하면 어떻게 될까? 이런 경우는 두가지 경우가 있다. 컴포넌트 스캔 vs 컴포넌트 스캔 : 충돌하는 빈들이 모두 컴포넌트 스캔 대상인 경우 수동 빈 등록 vs 컴포넌트 스캔 : 컴포넌트 스캔한 빈과 직접 등록해준 빈의 이름이 같은 경우 1. 컴포넌트 스캔 vs 컴포넌트 스캔 : 컴포넌트 스캔으로 등록했는데 같은 이름의 빈을 또다시 컴포넌트 스캔으로 등록하려는 경우 @Component("service") public class MemberServiceImpl implements MemberService { @Component("service") public class OrderServiceImpl implements OrderService{ 두 클래스를 serv..

[섹션6-3] 필터

앞에서 컴포넌트 스캔 대상이 되는 몇 가지 어노테이션이 있었다. 그렇다면 해당 어노테이션이 아니더라도 컴포넌트 스캔 대상이 되도록 할 수는 없을까? 바로 이 기능을 담당하는 것이 필터이다. 우리가 일상생활에서 쓰는 필터는 '걸러내는 틀' 이다. 이것을 스프링의 관점으로 생각해본다면 필터란 무엇을 빈으로 등록하고, 등록하지 않을지 걸러내는 것 이다. 필터 컴포넌트 스캔 대상에 추가할 어노테이션 package hello.core.scan.filter; import java.lang.annotation.*; @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface MyIncludeComponent { /..

[섹션6-2] 탐색할 위치와 기본 스캔 대상

탐색할 패키지의 시작 위치 지정 모든 자바 클래스를 다 컴포넌트 스캔하면 시간이 오래 걸린다. 그래서 꼭 필요한 위치부터 탐색하도록 시작 위치를 지정할 수 있다. @ComponentScan( basePackages = "hello.core.member", //시작 패캐지 지정 excludeFilters= @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Configuration.class ) ) basePackages : 탐색할 패키지의 시작 위치를 지정한다. 이 패키지를 포함해서 하위 패키지를 모두 탐색한다 baseClasses : 지정한 클래스의 패키지를 시작 패키지로 지정 만약 지정하지 않으면 @ComponentScan이 붙은 설정 정보의..