spring은 의존성 주입(DI)와 제어의 역전(Ioc)이라는 핵심적인 개념을 가진다.
객체 간의 의존 관계를 코드가 아닌 외부(설정)에서 주입해주는 개념과 객체 생성 및 생명주기 관리를 개발자가 하지 않고 스프링 컨테이너에 위임한다는 개념인데 오늘 배울 2가지 어노테이션은 spring을 사용시 좀 더 편리하게 객체를 주입할 수 있게 해주는 역할을 한다.
@Autowired는 Spring 2.5 (2007년)에서부터 본격적으로 도입됐다. 이때부터 리플렉션 기반의 자동 주입이 폭넓게 쓰이기 시작했다. @Autowired를 사용하기 전까지는 아래 코드처럼 .java와 .xml 2개 파일을 작성해 주어야 했다. 또한 생성자 주입방식, 필드 세터 3가지 주입 방식을 모두 사용할 수 있도록 설정되어 있고 required의 값에 따라서 null로 상요할 수 있다.
// 디폴트로 ture가 지정되어 있다.
@Autowired(required = true)
public MyService(MyRepository repo) {
this.repo = repo;
} // spring이 반드시 생성자에 필요한 의존성을 주입할 수 있어야 한다.
// 주입할 수 있는 빈(MyRepository repo)이 없으면 => 애플리케이션 실행 시 에러 발생 ‼️
@Autowired(required = false) //
public MyService(MyRepository repo) {
this.repo = repo;
} // 이 경우에는 빈이 없더라도 주입을 생략 가능 즉, repo가 null이 될 수 있다.
간단한 코드라서 괜찮아 보이겠지만, 프로젝트가 복잡해지면 생각이 크게 달라질거 같다. 특히 .xml을 작성해야 하는것은 지금 생각하면 끔찍하다고 생각한다.
// MemberService.java
public class MemberService {
private MemberRepository memberRepository;
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
<!-- applicationContext.xml -->
<beans>
<bean id="memberRepository" class="com.example.MemberRepository" />
<bean id="memberService" class="com.example.MemberService">
<property name="memberRepository" ref="memberRepository" />
</bean>
</beans>
스프링 2.5 이후에는 애너테이션 기반 자동 주입으로 이전 코드보다 훨씬 깔끔해졌다.
(선배 개발자님들은 어떻게 이거 안쓰고 개발했지?ㅠㅠ )
@Component
public class MemberService {
private final MemberRepository repo;
@Autowired
public MemberService(MemberRepository repo) {
this.repo = repo;
}
}
// 생성자 주입방식 (제일 권장되는 방식)
@Component
public class MemberService {
private final MemberRepository memberRepository;
@Autowired // 생략 가능 (생성자가 1개일 경우)
public MemberService(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
// 필드 주입 방식
@Component
public class MemberService {
@Autowired
private MemberRepository memberRepository;
}
// 세터 주입방식
@Component
public class MemberService {
private MemberRepository memberRepository;
@Autowired
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
}
리플렉션
| 항목 | @Autowired | @RequiredArgsConstructor |
|---|---|---|
| 주입 방식 | 필드 / 생성자 / 세터 주입 | 생성자 주입만 ‼️ |
| 필드 선언 | 일반 필드도 가능 | final 필드만 ‼️ |
| 목적 | 의존성 주입 | 안전하고 깔끔한 생성자 주입 자동화 |
| 주입 대상 | 명시된 대상 | final 필드 전부 |
| 장점 | 간단하고 유연함 🟢 | 불변성, 테스트 용이성, 명확한 의존성 표현 |
| 단점 | 필드 주입 시 단위 테스트 어려움 | final만 사용 가능 (제약 있음) |
Understanding @Autowired in Spring: A Comprehensive Guide
https://dev.to/tiuwill/understanding-autowired-in-spring-a-comprehensive-guide-1i6k
Annotation Interface Autowired
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html
@Autowired의 동작원리
https://beststar-1.tistory.com/40
내가 @RequsiredArgsConstructor를 통해 DI를 한 이유
https://velog.io/@yardyard/%EB%82%B4%EA%B0%80-RequiredArgsConstructor%EB%A5%BC-%ED%86%B5%ED%95%B4-DI%EB%A5%BC-%ED%95%9C-%EC%9D%B4%EC%9C%A0onstructor
코드로 배우는 스프링] 1-2. 스프링의 역사, 특징과 의존성 주입, 동작 방식|작성자 1ilsang
https://blog.naver.com/1ilsang/221386784142