우리는 지금 까지 클래스를 빈에 등록하여 생성해줄 때 다음처럼 작성하였다.
public class A {
private String bla;
...
}
//다른 어딘가
@Configuration
public class configClass{
@Bean
public A returnA(){
return new A();
}
}
//의존성을 주입 받는 또 다른 어딘가
public class C{
@Autowired
A a;
//기타 코드들
}
그런데 매번 클래스를 추가할 때 마다 Configuration 클래스에 등록을 해줘야 할까?
그건 아니다. 단순히 클래스한테 @Component 어노테이션을 달아주면 알아서 해당 클래스를 반환하는 빈을 생성해 준다.
이때 만약 해당 컴포넌트를 사용하는 패키지와 어플리케이션이 실행되는 패키지가 다르면 어플리케이션이 실행되는 클래스에 @ComponentScans("패키지명")을 해줘야 한다.
그런데 이런 상황이 발생할 수 있다.
우리는 느슨한 결합을 위해 추상화를 이용하였다.
public interface Car {
private String carName();
//기타 코드들//
}
//다른 어딘가
@Component
public class BMW implements Car {
//구현내용//
}
//다른 어딘가 2
@Component
public class KIA implemnts Car {
//구현내용//
}
//다른 어딘가 3
@Component
public class sampleClass{
@Autowired
Car car;
}
이렇게 되어 있으면 car에 어떤 자동차가 들어가는지 모르기 때문에 NoUniqueBeanDefinitionException이 발생한다.
이를 @Primary를 이용하여 해결할 수 있기는 하다
public interface Car {
private String carName();
//기타 코드들//
}
//다른 어딘가
@Component
public class BMW implements Car {
//구현내용//
}
//다른 어딘가 2
@Component
@Primary
public class KIA implemnts Car {
//구현내용//
}
//다른 어딘가 3
@Component
public class sampleClass{
@Autowired
Car car;
}
이렇게 해주면 KIA가 맵핑되지만 언제나 default만을 고집할 수는 없다
이를 위해서는 @Bean에서 사용했던 것 처럼 @Quialifier를 이용하면 된다.
public interface Car {
private String carName();
//기타 코드들//
}
//다른 어딘가
@Component
@Qualifier("BMW")
public class BMW implements Car {
//구현내용//
}
//다른 어딘가 2
@Component
@Qualifier("KIA")
public class KIA implemnts Car {
//구현내용//
}
//다른 어딘가 3
@Component
public class sampleClass{
@Autowired
@Qualifier("KIA")
Car car;
}
를 해주면 KIA가 car에 주입된다
물론 있다. 총 3가지 종류가 있다.
우리가 아는 흔한 방법
@Component
public class SampleClass{
@Autowired
Dependency dependency1;
@Autowired
Dependency dependency2;
}
@Component
public class SampleClass{
Dependency dependency1;
Dependency dependency2;
@Autowired
public void setDependency1(Dependency1 dependency1){
this.dependency1 = dependency1;
}
@Autowired
public void setDependency2(Dependency2 dependency2){
this.dependency2 = dependecy2;
}
}
이렇게 Setter를 정의한후 해당 함수에다가 @Autowired를 붙여도 된다.
@Component
public class SampleClass{
Dependency dependency1;
Dependency dependency2;
@Autowired
public SampleClass (Dependency1 dep1, Dependency2 dep2)
{
this.dependency1 = dep1;
this.dependency2 = dep2;
}
}
이렇게 생성자에다가 붙여도 의존성 주입이 된다.