9. 어노테이션

Seungjae·2021년 1월 24일
0

Spring 다지기

목록 보기
9/14

어노테이션


지금까지는 xml로 DI명세서를 작성했습니다. 하지만 xml로 DI명세서를 작성하는 것은 설정이 많아지면 많아질수록 직관성이 떨어지고 복잡한 일이 되었습니다. 그래서 어노테이션이 등장하였습니다. 어노테이션은 설정파일을 따로 수정하는 것이 아닌 소스코드와 함께 특별한 표기로써 작성하기 때문에 더욱 직관적이고 간편하게 사용할 수 있습니다.

@Autowird

context 네임스페이스를 사용해야합니다.

<context:annotation-config />

위와 같은 태그를 사용해서 @Autowired가 사용된 부분을 DI해줄 수 있습니다. 그렇다면 이 @Autowired는 무엇을 기준으로 DI해주는 것일까요? @Autowired는 자료형을 기준으로 DI해줍니다.

@Autowired // 자료형 기본으로 찾음!
@Override
public void setExam(Exam exam) {
	this.exam = exam;
}

위와 같은 코드가 있을 때, @Autowired는 IOC컨테이너에서 Exam에 해당하는 객체를 찾습니다. 흥미로운 점은 Exam 뿐만아니라 이것이 인터페이스일 경우 이 인터페이스를 구현한 구현클래스 또한 찾을 수 있다는 것입니다. 그렇다면 만약 Exam을 구현한 객체가 IOC컨테이너에 여러개라면 어떻게 될까요? 오류가 납니다. 따라서 이 경우 구분을 해줘야합니다.

@Qualifier


위와 같은 경우 @Qualifier을 이용해서 구분해줍니다. Exam 객체에 id로 이름을 부여한뒤 @Qualifier로 특정한 이름의 객체를 찾는 것입니다.

<bean id="exam1" class="spring.di.entity.OhExam" p:korean="10" p:english="10" />
	
<bean id="exam2" class="spring.di.entity.OhExam" p:korean="20" p:english="20" />
@Autowired // 자료형 기본으로 찾음!
@Qualifier("exam1") // 찾은 것이 여러개일 경우 부여한 아이디로 구분!
@Override
public void setExam(Exam exam) {
	this.exam = exam;
}

위의 경우 id가 exam1인 객체를 IOC컨테이너에서 찾아서 DI해줍니다.

@Autowired 위치

@Autowired는 크게 3가지 위치에 사용할 수 있습니다.

  1. private Exam exam; -> 필드에서
  2. 오버로딩한 생성자에서
  3. setter 함수에서

이때 1번의 경우 기본 생성자를 호출하면서 DI가 이루어집니다. 나머지의 경우 각각 오버로딩한 생성자를 호출하면서, setter 함수를 호출하면서 DI가 이루어집니다. 그리고 2번의 경우를 사용할 때는 유의해야할 점이 있습니다. 오버로딩 생성자의 경우 인자를 여러개 받을 수 있다는 가정이 있기에 @Qualifier가 오류를 일으킵니다. 이 경우에는 각 인자마다 @Qualifier를 붙혀서 명시함으로써 해결할 수 있습니다.(인자가 하나여도 동일하게 인자에다 붙혀야 합니다.)

@Autowired  
public InlineExamConsole(@Qualifier("exam1")Exam exam) {
	System.out.println("오버로딩 생성자!");
	this.exam = exam;
}

required


@Autowired의 속성중 required라는 것이 있습니다. @Autowired로 IOC 컨테이너에서 객체를 찾는데 없을 경우 오류를 냅니다. 하지만 가끔씩 로직에서 찾으려는 객체가 없을 때 다른 로직을 진행하는 경우도 있을 것입니다. 그때 사용하는 것이 required입니다.

@Autowired(required = false) 
@Qualifier("exam1")
private Exam exam;

이렇게 required를 false로 설정해줄경우, 객체가 없더라도 오류가 나지않고 진행되게 됩니다. 따라서 IOC 컨테이너에 객체가 존재하지 않을 때 로직을 분류해서 사용할 수 있습니다.

public void print() {
	if(exam == null) {
		System.out.printf("total is %d, avg is %f\n", 0, 0.0);
	} else {
		System.out.printf("total is %d, avg is %f\n", exam.total(), exam.avg());			
	}
}
profile
코드 품질의 중요성을 아는 개발자 👋🏻

0개의 댓글

관련 채용 정보