inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

스프링 핵심 원리 - 기본편

다양한 의존관계 주입 방법

필드 주입의 문제점에 대해 궁금한게있습니다.

588

메모장

작성한 질문수 38

1

20:20 정도부터 나오는 필드주입에서 궁금한점이 있습니다.

김영한님 말씀중에선 강의예제중, 

@Autowired private MemberRepository memberRepository;
@Autowired private DiscountPolicy discountPolicy;

위처럼 필드주입을 하게되면 memberRepository  나discountPolicy  의 값을 변경할수없고 테스트코드에서  순수한 자바로 테스트할수있는 방법이 없다고 하셨습니다.

그런데 제 생각으로는 그렇게 생각하면 기본방법인 생성자 주입도 결국 생성되고나면 변경할수없고 순수한 자바로 테스트할수있는 방법이 없는것 같다고 생각이 되었습니다. 왜냐면 둘다 현재 수동설정이 아닌 어노테이션을 통한 자동설정으로 이루어지고있으므로 무얼 넣어줄지는 해당 구현체의 어노테이션을 추가,삭제해주지않는이상 바꿀수 없다고 생각했기 때문입니다.

이부분에대해서 설명주시면 감사하겠습니다!

oop spring

답변 1

3

David

안녕하세요. 메모장님, 공식 서포터즈 David입니다.

.

순수한 자바로 테스트한다는 말을 잘 생각해보시면 좋습니다.
스프링 컨테이너를 실행하지 않은 상태(필드 주입을 위한 @Autowired가 동작하지 않음)에서는 생성자나 수정자가 없으면 필드에 구현체를 넣을 방법이 없습니다.

즉, 필드 주입을 사용하고 있는 클래스를 테스트하려면 스프링 컨테이너를 통해 의존관계가 설정되어야 합니다. 만약, 필드 주입을 사용하는데 스프링 컨테이너를 사용하지 않는다면 Null Pointer Exception이 발생할 것 입니다. 해당 필드에 구현체가 존재하지 않기 때문입니다.

따라서 생성자 주입을 사용하게 되면 스프링과 결합된 코드(테스트를 위해 스프링 컨테이너를 실행해야 하는 코드)가 아닌 순수한 자바 코드(스프링 컨테이너를 실행하는 게 없는 코드)로 의존관계를 주입하고 테스트를 할 수 있습니다.

.
감사합니다.

0

메모장

친절한 답변 정말 감사합니다!

그런데 제가 질문을 다소 잘못드린거같아 한번더 여쭤보고싶은게 있습니다 ㅠ

제가 질문드릴때 생각했던 테스트는 @Test를 붙이는 테스트 코드클레스를 질문드렸던거지만, 말씀주신 순수한 자바로 테스트한다고 하셨던 이부분의 테스트는 현재 의존관계가 주입받고 있는 클레스에서의 테스트를 말씀하신걸까요?

제가 헷갈리는부분은 필드주입이던 생성자주입이던 우선 어노테이션을 통해 의존관계를 주입받아 해당 빈을 가져온 상태고, 이것을 @Test가 붙은 테스트코드에서 사용하려면 결국 둘다 ApplicationContext(스프링 컨테이너)를 사용해야하기에 둘다 순수한자바 테스트가 안된다고 생각되었기 때문입니다. 

1

David

강의에서 언급하신 순수한 자바로 테스트한다는 말은 "스프링 컨텍스트"를 띄우지 않은 상태에서 하는 테스트를 말하는 것입니다.

그렇기 때문에 순수한 자바로 테스트를 진행하게 되면 필드주입은 발생하지 않습니다. 필드 주입은 스프링 컨텍스트에서 @Autowired를 감지하여 해당 필드에 들어갈 빈을 컨테이너로부터 가져와야 합니다. 그러나 스프링 컨텍스트를 사용하지 않기 때문에 필드주입이 발생하지 않습니다. 마찬가지로 생성자 주입도 "자동"으로 일어나지 않습니다.

다만, 생성자 주입의 경우 스프링 컨텍스트를 사용하여 자동으로 주입되지 않지만 수동으로 의존관계를 주입할 순 있습니다. 직접 구현체를 생성하고 생성된 구현체를 생성자에 전달하면 되니깐요.

0

메모장

답변 감사합니다. 말씀주신걸 제가 이해한바로는 결국 필드주입은 스프링 컨텍스트를 의존해야 주입받을수있어서 순수자바로 테스트를 못하지만, 생성자 주입의 경우 현재 강의의 초기내용처럼 AppConfig를 통해 주입을 받아 테스트를 할수있기때문에 순수자바로 테스트를 했다고 볼수있다. 

라고 이해했습니다. 맞을까요?

0

David

꼭 AppConfig가 아니더라도 됩니다. 의존관계에 필요한 객체를 생성해서 생성자의 파라미터로 넘겨주기만 하면 됩니다. 나머진 이해하신 부분이 맞습니다.

1

rweteam

안녕하세요 저도 이와 비슷한 궁금증이 생겨 답변을 읽다가 혼란에 빠져버려서 질문드리고싶습니다.

 

순수 자바코드로 테스트한다는 것은 ApplicationContext를 사용하지 않는다는 것이고, @Autuwired도 동작하지 않고, 스프링 컨테이너가 없기때문에 Bean이라는 것도 없지 않나라는 생각이 들었습니다.

 

BeforeEach를 통해서 AppConfig를 이용해 MemberService, OrderService 객체를 생성하고 있습니다.

AppConfig에서는 각 메소드에 @Bean어노테이션이 붙어있고 클래스에도 @Configuration이 붙어있는데 이 어노테이션들도 순수 자바코드로 테스트할 때는 전혀 동작하지 않는 어노테이션인가요?

 

다시 한번 정리해보자면

순수 자바코드 테스트 에서는 ApplicationContext를 사용하지 않는다.

-> 스프링 컨테이너가 없다.

-> Bean을 관리하지 않는다.

-> @Autowired 포함 @Bean, @Configuration도 동작하지 않는다.

 

맞을까요..?

0

David

네, 맞습니다.

구현체가 동적으로 정해질 때, 팩토리 기법을 사용하나요?

0

49

2

MemberService의 인터페이스를 왜 사용하는지 궁금합니다.

0

72

1

롬복 @Setter를 써야 하는 상황이 있는건가요?

0

87

1

빈 등록 메서드의 파라미터가 빈이 아니어도 되나요?

0

79

1

테스트 속도가 나중에 영향이 있을까요?

0

75

1

gradle 설정 안떠서 질문 남깁니다!

0

116

2

build.gradle로 프로젝트를 여는 이유

0

81

1

provider 사용하는 이유

0

85

1

다음 강의 뭘 들어야 할까요

0

123

2

프로토타입 빈, 직접 destroy 호출 안 할 경우

0

62

1

beanB

0

79

2

퀴즈다시풀기

0

63

1

Gradle로 바꿔도 오류가 똑같이 발생하네요 ㅠㅠ

0

90

2

"중복 등록과 충돌" 강의에서 강사님과 다른 에러가 발생합니다.

0

63

3

run 실행했는데 결과창이 이렇게 뜨네요 왜 그런건가요>

0

102

2

도메인의 정의?

0

57

1

ApplicationContext 질문입니다.

0

60

1

@Scope의 proxyMode를 사용할때 단위 테스트 방법

0

86

2

ai api 선정하기 관련 질문

0

115

2

생성자 자동주입 관련해서

0

60

1

생성자 직접 호출 vs 팩토리 메서드 패턴

0

93

2

Spring에서 SessionScope와 RequestScope는 함께 사용되나요?

1

63

1

12:25

0

75

2

appConfig.xml 오류

0

127

1