@Autowired
@Autowired를 이용하면 필요한 의존 객체의 “타입"에 해당하는 Bean을 찾아 주입한다.
(의존성 : 하나의 객체 내에서 필요에 의해 다른 객체를 사용해야 할 경우 사용하는 것 의미)
DI(Dependency Injection = 의존성 주입)은 Spring의 특성으로 하나의 객체 내에서 필요에 의해 다른 객체를 생성자 또는 Setter를 통해 주입시키는 것을 의미한다.
@Autowired annotation을 통해 "인터페이스를 선언한 변수에 자동적으로 그 인터페이스를 재정의한 객체를 주입시킨다."
- 생성자
- setter
- 필드
위의 3가지의 경우에 Autowired를 사용할 수 있다. 그리고 Autowired는 기본값이 true이기 때문에 의존성 주입을 할 대상을 찾지 못한다면 애플리케이션 구동에 실패한다.
회원 Service에 대한 단위 테스트 시에 @Autowired annotation을 사용하여 MemberService와 MemberRepository 변수를 선언하였는데, 언제 써야하는지 아직 감이 잘 안온다..
@ExtendWith(SpringExtension.class)
@SpringBootTest
@Transactional
class MemberServiceTest {
@Autowired
MemberService memberService;
@Autowired
MemberRepository memberRepository;
}
실제 field injection 시 사용한 코드를 살펴보면 아래와 같다.
-
@Autowired //field injection private MemberRepository memberRepository;
- 위와 같이 Field 경우 Access(변경)가 불가능하므로 주입하기 힘드나, 아래와 같은 방식으로 사용하면 Test 시 자유롭게 변경 가능하다.
private MemberRepository memberRepository; @Autowired public void setMemberRepository(MemberRepository memberRepository) { this.memberRepository = memberRepository; }
- 위 같은 setter 또한 application 동작시 수정하게 되면 문제가 발생할 수 있으므로 요즘에는 생성자를 사용하여 injection하는 방법을 권장한다.
private MemberRepository memberRepository; @Autowired public MemberService(MemberRepository memberRepository) { this.memberRepository = memberRepository; }
- lombok에 @AllArgsConstructor의 경우 모든 필드에 대한 생성자를 만들어줌
- @RequiredArgsConstructor의 경우 final로 선언된 필드에 대해서만 생성자를 만들어줌
@Service @Transactional(readOnly = true) //all JPA changes should be executed in Transaction @RequiredArgsConstructor // create constructor for final field public class MemberService { private final MemberRepository memberRepository; }
참고
https://devlog-wjdrbs96.tistory.com/166
'Web > Spring Boot' 카테고리의 다른 글
[SpringBoot]Logging과 Log Level (0) | 2021.11.25 |
---|---|
[SpringBoot]banner.txt만들기 (0) | 2021.11.22 |
[Spring Boot]Docker-compose (0) | 2021.10.27 |
[Spring Boot]Docker 이미지 빌드 (0) | 2021.10.27 |