본문 바로가기

Spring/Dependency Injection

[Spring Framework] @Autowired 사용 위치와 Required

728x90
반응형

'뉴렉처' 님의 채널(www.youtube.com/user/newlec1)을 바탕으로 제작한 블로그 글입니다:)

 

 

이번 시간에는 @Autowired를 붙이는 위치와 @Required란 무엇인지에 대해서 알아보고자합니다.

 

 

 

@Autowired의 위치

 

우선 Autowired는 아래와 같은 위치에서 사용할 수 있습니다.

 

 

1. 필드 위 (기본 생성자에서 객체 생성)

2. setter위

3. 오버로드 생성사 위

 

public class AnimalPrintName implements AnimalPrint {

	@Autowired // 1번 경우
	Animal animal;
	
	public AnimalPrintName() {
		// TODO Auto-generated constructor stub
	}
	
	@Autowired // 3번 경우
	public AnimalPrintName(Animal animal) {
		this.animal = animal;
	}

	@Override
	public void print() {
		System.out.printf("Name is %s", animal.getName());

	}

	@Autowired // 2번 경우
	@Qualifier("animal2")
	@Override
	public void setAnimal(Animal animal) {
		this.animal = animal;
		
	}

}

 

 

좀 더 자세히 알아봅시다.

 

 

1번 경우는 기본 생성자인 AnimalPrintName() 를 호출하는 과정에서 injection을 하게 됩니다. 

2번 경우인 setter 위에 @Autowired를 붙이게 되면, setter 함수가 호출되면서 injection이 됩니다.

 

 

그렇다면 이 말은 기본 생성자가 없는 상태에서 필드 위에 @Autowired를 붙이게 되면 오류가 난다는 의미입니다.

즉, 오버로드 생성자는 있지만, 기본 생성자는 명시하지 않은 경우에 문제가 생기는 것이죠.

 

다만 오버로드 생성자와 기본 생성자 둘 다 명시되지 않는다면, 자동으로 컴파일러가 기본 생성자를 알아서 만들기 때문에 이런 경우는 예외입니다.

 

 

 

그러면 마지막으로 3번 경우에 대해서 좀 더 알아봅시다.

3번 경우는 특이한 점이 하나 있는데요,

바로 다음과 같이 적어도 에러가 난다는 점입니다.

 

@Autowired
@Qualifier("animal1")
public AnimalPrintName(Animal animal){
	...
}

 

@Autowired를 붙이고, 객체를 정확하게 찾아 injection하기 위해 @Qualifier까지 붙여줬는데 에러가 나는 이유는 무엇일까요?

바로 이와같은 생성자는 AnimalPrintName(Animal animal) 과 같이 매개변수가 하나라고 적어주어도,

매개변수가 여러개 일 수 있다는 가정을 하기 때문입니다.

 

즉,  AnimalPrintName(Animal animal1, Animal animal2) 처럼 매개변수가 여러개가 올 수도 있다고 취급하는 것이죠.

따라서 우리는 함수 선언 위에 @Qualifier을 적는 것이 아니라, 아래와 같이 매개변수 옆에 적어주어야 합니다.

 

@Autowired
public AnimalPrintName(@Qualifier("animal1")Animal animal){
	...
}

 

 

 

 

Required

 

우리가 지금까지 봐왔듯이, 만약 @Autowired를 하였을 때에 xml에서 알맞은 객체를 찾아 injection하지 못하면 대번 빨간줄과 함께 에러가 나게 됩니다.

 

하지만, 필요에 따라서 내가 객체를 injection하지 못했다면, 하지 못한대로 그냥 코드를 실행시키고 싶을 때도 있겠죠?

즉, xml에 알맞은 객체가 없어서 animal이라는 필드에 injection을 하지 못했지만,

print 할 때에는 animal이 null일 때에 "이름을 입력하세요" 와 같은 문구를 출력시키는 것 처럼요.

 

 

그럴 때 사용하는 것이 Required입니다.

Required는 아래 중에서 선택해서 사용할 수 있습니다.

1. @Autowired(required = false) : 반드시 injection 해야 할 필요는 없을 때

2. @Autowired(required = true) : 반드시 injection 해야 할 때

 

 

그러면 required 를 false로 하여 아래의 코드를 실행시켜보겠습니다.

 

- AnimalPrintName.java

public class AnimalPrintName implements AnimalPrint {

	@Autowired(required = false)
	@Qualifier("none")
	Animal animal;
	
	public AnimalPrintName() {
		// TODO Auto-generated constructor stub
	}
	
	public AnimalPrintName(Animal animal) {
		this.animal = animal;
	}

	@Override
	public void print() {
		if (animal == null)
			System.out.printf("동물이 없습니다");
		else 
			System.out.printf("Name is %s", animal.getName());

	}

	@Override
	public void setAnimal(Animal animal) {
		this.animal = animal;
		
	}

}

 

 

현재 xml에 none 이라는 animal은 없기 때문에 injection이 되지 않았으니 print의 if (animal == null) 이 true가 될 것입니다.

아래와 같이 결과가 나온 것을 확인할 수 있습니다 :)

 

 

 

 

728x90
반응형