[Spring] 자동으로 빈 생성하기

Martin the dog·2023년 6월 29일

스프링 복습하기

목록 보기
2/15

@Component로 빈생성 줄이기

우리는 지금 까지 클래스를 빈에 등록하여 생성해줄 때 다음처럼 작성하였다.

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가지 종류가 있다.

@Autowired

우리가 아는 흔한 방법

@Component
public class SampleClass{
	@Autowired
    Dependency dependency1;
    @Autowired
    Dependency dependency2;
}

Setter를 이용한 방법

@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;
    }
}

이렇게 생성자에다가 붙여도 의존성 주입이 된다.

profile
Happy Developer

0개의 댓글