Autowiring이란 Spring이 의존성 Bean을 자동으로 주입하도록 하는 기능이다.
@Autowired
어노테이션을 사용하여 Autowiring을 구현할 수 있다.
의존성을 주입하고자 하는 위치에 따라 다음과 같이 @Autowired
어노테이션을 사용할 수 있다. @Autowired
어노테이션은 생성자, 메서드, 필드, 파라미터 등에 달 수 있다.
컴포넌트의 생성자를 통해 의존성을 주입하려면 해당 생성자에 어노테이션을 단다.
@Component
public class ExampleBean {
private Dependency dependency;
@Autowired
public ExampleBean(Dependency dependency) {
this.dependency = dependency;
}
...
}
컴포넌트의 생성자가 하나 뿐이면 어노테이션을 생략할 수 있다.
setter를 통해 의존성을 주입하려면 해당 setter에 어노테이션을 단다.
@Component
public class ExampleBean {
private Dependency dependency;
@Autowired
public void setDependency(Dependency dependency) {
this.dependency = dependency;
}
...
}
필드에 직접 의존성을 주입하려면 해당 필드에 어노테이션을 단다.
@Component
public class ExampleBean {
@Autowired
private Dependency dependency;
...
}
Autowiring은 기본적으로 타입을 통해 삽입할 Bean을 결정한다. 따라서 같은 타입의 Bean 후보가 여러 개인 경우 문제가 발생할 수 있다. 이를 해결하기 위해 다음과 같은 방법을 사용할 수 있다.
@Primary
로 우선권 부여하기@Primary
는 같은 타입의 Bean이 여러 개 정의될 때 해당 Bean이 우선적으로 주입되도록 우선권을 부여하는 어노테이션이다.
@Component
클래스에 달기아래 예시에서 PrimaryBean
과 SecondaryBean
은 모두 ExampleBean
을 상속한다. ExampleService
의 생성자로 의존성을 주입할 때 @Primary
가 달린 PrimaryBean
가 우선적으로 주입된다.
클래스 레벨에서 @Primary
를 사용하려면 컴포넌트 스캔을 사용해야 한다.
@Component
public class ExampleService {
private ExampleBean exampleBean;
@Autowired
public ExampleService(ExampleBean exampleBean) {
this.exampleBean = exampleBean;
}
...
}
@Component
@Primary
public class PrimaryBean extends ExampleBean { ... }
@Component
public class SecondaryBean extends ExampleBean { ... }
@Bean
메서드에 달기@Primary
를 @Bean
메서드에 달면 해당 Bean이 우선적으로 주입된다.
@Component
public class ExampleService {
private ExampleBean exampleBean;
@Autowired
public ExampleService(ExampleBean exampleBean) {
this.exampleBean = exampleBean;
}
...
}
@Configuration
@ComponentScan
public class AppConfig {
@Bean
@Primary
public ExampleBean primaryBean() { ... }
@Bean
public ExampleBean secondaryBean() { ... }
// ...
}
@Qualifier
로 의존성 연결하기Bean을 정의할 때 @Qualifier
를 사용하고, 해당 Bean을 주입할 위치(필드 또는 메서드/생성자의 파라미터)에 @Qualifier
어노테이션을 달면 주입될 의존성을 명시할 수 있다.
@Component
public class ExampleService {
@Autowired
@Qualifier("first")
private ExampleBean exampleBean;
...
}
@Configuration
@ComponentScan
public class AppConfig {
@Bean
@Qualifier("first")
public ExampleBean firstBean() { ... }
@Bean
public ExampleBean secondBean() { ... }
}
@Component
public class ExampleService {
private ExampleBean exampleBean;
@Autowired
public ExampleService(@Qualified("first") ExampleBean exampleBean) {
this.exampleBean = exampleBean;
}
}
@Configuration
@ComponentScan
public class AppConfig {
@Bean
@Qualifier("first")
public ExampleBean firstBean() { ... }
@Bean
public ExampleBean secondBean() { ... }
}