DI란 외부에서 두 객체 간의 관계를 결정해주는 디자인 패턴으로,
인터페이스를 사이에 두어 클래스 레벨에서는 의존관계가 고정되지 않도록 하고 런타임 시에 관계를 동적으로 주입하여 유연성을 확보하고 결합도를 낮출 수 있게 해준다.
의존성이란 한 객체가 다른 객체를 사용할 때 의존성이 있다고 한다.
@Autowired - 스프링의 자동 주입 기능을 위한 어노테이션. 해당 타입의 빈을 찾아서 필드에 할당.
⚠️ 주의사항 ⚠️
NoSuchBeanDefinitionException@Qualifier(”빈이름”) 어노테이션을 이용해 꼭 사용할 빈을 지정해줘야 한다. 그렇지 않을 경우, NoUniqueBeanDefinitionException순환 참조 문제
@Service
public class ServiceA {
@Autowired
private ServiceB serviceB; // ServiceB를 주입받음
}
@Service
public class ServiceB {
@Autowired
private ServiceA serviceA; // ServiceA를 주입받음
}
불변성(final) 보장 불가
테스트 어려움 - 테스트 코드 의존성 주입이 어려움
의존성 관계가 불명확
단일 책임 원칙 위반 가능성
@Autowired 책에서는 이 방법을 많이 사용하지만,
@Autowired 필드 주입은 점점 사용을 지양하는 추세생성자 주입이 권장됨두 개 이상의 설정 파일을 사용하는 또 다른 방법의 어노테이션
@Configuration
@Import(AppConfig2.class) // 1개
@Import({AppConfig1.class, AppConfig2.class}) // 2개 이상
class AppConfImport {...}
@Import로 가져오는 클래스는 어떠한 스프링 관련 어노테이션이 없더라도 스프링 컨테이너가 관리하는 빈으로 등록된다.
하지만, 코드의 의도와 유지보수성을 위해서 명시적으로 기입해주는 것이 좋다.
다중 @Import 사용시 최상위 설정 클래스 한 개만 사용하면 된다.
자동 주입 가능한 빈이 두 개 이상이면 자동 주입할 빈을 지정할 수 있는 방법이 필요하다. 이때 해당 어노테이션을 사용한다.
사용 방법
@Bean 어노테이션을 붙인 빈 설정 메서드
// 1. 해당 빈의 한정 값으로 "printer"를 지정한다.
@Bean
@Qualifier("printer")
public MemberPrinter memberPrinter1() {
return new MemberPrinter();
}
// 2. @Autowired 어노테이션에서 자동 주입할 빈을 한정
@Autowired
@Qualifier("printer")
public void setMemberPrinter(MemberPrinter printer) {
this.printer = printer;
}
빈 이름과 기본 한정자
빈 설정에 @Qualifier 이 없으면 빈의 이름을 한정자로 지정한다.
@Configuration
public class AppCtx2 {
@Bean
public MemberPrinter printer() {
return new MemberPrinter();
}
@Bean
@Qualifier("mprinter")
public MemberPrinter printer2() {
return new MemberPrinter();
}
@Bean
public MemberInfoPrinter infoPrinter() {
MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
return infoPrinter;
}
}
| 빈 이름 | @Qualifier | 한정자 |
|---|---|---|
| printer | printer | |
| printer2 | mprinter | mprinter |
| infoPrinter | intoPrinter |
Gradle이나 Maven을 이용하여 외부 라이브러리를 프로젝트에 추가하는 행위도 의존성 주입이라고 부른다.
프로젝트 레벨의 의존성이고, 빌드시점에 의존성을 해결한다.
위 설명은 스프링 컴포넌트에 대한 의존성 주입에 대한 이야기이다.
애플리케이션 내부의 객체 간 의존성이고, IoC컨테이너가 관리하며, 런타임시에 스프링 의존성이 해결된다.
책 - 초보 웹 개발자를 위한 스프링 5 프로그래밍 입문
Claude.ai