Notice
Recent Posts
Recent Comments
Link
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

쉽지않은 블로그

[Spring] Bean 의 의존관계 주입 방법 본문

개발공부/스프링

[Spring] Bean 의 의존관계 주입 방법

쉽지않네 2021. 4. 19. 00:37

지난 글에 스프링 Bean 이 무엇인지에 대해 설명하면서

@Component를 사용한 방식을 언급했었다

 

이 방식을 사용할 경우 다른 Bean 과의 의존관계를 갖는 경우 어떻게 처리를 해야 될 것인지에 대해 정리해본다.

 

CarserviceImpl.java
@Component
public class CarServiceImpl implements CarService{
	private EngineService engineService;
	...
	...
}
 
******************************************
EngineBMW.java
@Component
public class EngineBMW implements EngineService{
	private int power = 10;
}

 

CarServiceImpl와 EngineBMW 클래스는 Bean으로 등록되어있는 상태이다

CarServiceImpl는 EngineService으로 구현된 무언가를 기대한다!!(4번 line)

 


1. 생성자 주입

 

Bean 은 싱글톤을 보장한다고 했다  싱글톤을 보장하기 위해선

클래스의 생성자( 즉 초기화)가 한번 호출될 것이다

이것의 의미는 불변이나 필수 의존관계 정의에 사용될 수 있다는 뜻이다.

 

다음은 클래스의 생성자를 이용한 주입방법이다

@Component
public class CarServiceImpl implements CarService{
	private final EngineService engineService;

	@Autowired   //생성자가 하나일 경우 @Autowired 생략가능
	public CarServiceImpl EngineService engineService){
		this.engineService = engineService;
	}
	
}
 

 

작동 순서는 이렇다 CarServiceImpl 의 의존관계 중 EngineService 인 것을 발견하고

EngineService 타입으로 등록된 빈이 있는지 찾는다

(물론 해당타입으로 검색된 빈의 결과가 하나만 있어야 된다....
중복될 경우 @Qualifier 나 @Primary  어노테이션을 생성자 인자에 적용하여 사용해줘야 한다)

 

의존관계 주입이 될 수도 있고 안될 수도 있는 경우는 @Nullable을 사용하여 인자를 처리해준다.

 

보통 생성자 주입은

컴포넌트 사용 전에 해당 컴포넌트의 의존성을 반드시 갖고 있어야 할 경우에 사용하는 게 좋다.

 

lombok 라이브러리의 도움을 받으면

@RequiredArgsConstructor을 이용하여 

다음과 같이 생성자 자체를 생략해줄 수 있다.

 

@RequiredArgsConstructor 어노테이션은 해당 클래스의 final 키워드가 붙은 필드들을 초기화하는 생성자를 자동으로 생성해준다.

@Component
@RequiredArgsConstructor
public class CarServiceImpl implements CarService{
	
	private final EngineService engineService;
}

2. 수정자 주입

 

차에 엔진을 언제든지 바꾸게 하고 싶을 경우 setter 메서드를 사용하는 것처럼

setter메서드를 일단 정의해놓고 

@Autowired를 이용하여  스프링 컨테이너에게 setter 메서드를 알려주는 방식이다

@Component
public class CarServiceImpl implements CarService{
	private EngineService engineService;

	@Autowired
	public setEngineService(EngineService engineService){
		this.engineService = engineService;
	}
	
}

 위아 같은 수정자 주입방식은 수정, 변화에 적극적으로 대응을 하고 싶을 때 사용하는 방식이다.

 


3. 필드 주입

 

final로 선언된 필드에 직접 @Autowired를 시키면 클래스 타입을 확인하여 필요한 Bean을 불러온다

@Component
public class CarServiceImpl implements CarService{
	
	@Autowired 
	private EngineService engineService;
	
}

이 방식의 단점은 

스프링을 이용하지 않는 자바 테스트 코드에서는 EngineService 타입의 Bean을 알아서 찾아오지 못한다

스프링 프레임워크 없이는 의존관계를 이해하지 못한다

사용하지 않는 것이 권고된다.

 


4. 일반 메서드 주입

 

특정 메서드를 선언한 후 필요한 인자들을 지정해준 후 @Autowired 어노테이션을 붙이면

내 마음대로 Bean 초기화 시 주입되는 인자들을 지정해줄 수 있다.

 

잘 사용되지는 않는다고 한다.

@Component
public class CarServiceImpl implements CarService{
	
	private EngineService engineService;

	public void init(EngineService engineService){
		this.engineService = engineService;
	}
	
}

 

 

 

참고문헌 : 

www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8#

Comments