이전 시간에 @Autowired를 통해 DI를 진행할 수 있었다. 하지만 어떠한 기준으로 작동이 되는 것인가에 대한 궁금증이 생긴다. 기본적으로 클래스 타입을 기준으로 DI가 진행이 된다고 한다. (인터페이스로 구현된 것도 매칭이 가능)
다음과 같이 xml파일에서 설정한 내용을
@Autowired로 바인딩했을 때 생성된 객체의 클래스(class="...")들이 기준이 된다는 것이다.
그래서 xml 내에 해당 객체가 매칭이될 때 굳이 id
쓰지 않아도 된다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<context:annotation-config/>
<!-- Exam exam = new NewlecExam(); -->
<bean class="spring.di.entity.NewlecExam" p:kor="10" p:eng="20"/>
<bean id="console" class="spring.di.ui.InlineExamConsole">
</bean>
</beans>
package spring.di.ui;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import spring.di.entity.Exam;
public class InlineExamConsole implements ExamConsole {
private Exam exam;
public InlineExamConsole() {
// TODO Auto-generated constructor stub
}
public InlineExamConsole(Exam exam) {
this.exam = exam;
}
@Override
public void print() {
System.out.printf("total is %d, avg is %f\n", exam.total(), exam.avg());
}
@Autowired
@Override
public void setExam(Exam exam) {
this.exam = exam;
}
}
동일하게 동작한다.
package spring.di;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import spring.di.ui.ExamConsole;
public class Program {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("spring/di/setting.xml");
ExamConsole console = (ExamConsole) context.getBean("console");
}
}
하지만 대응대는 객체가 여러 개 존재하여 혼란이 야기된다면 이 때 @Qualifier가 사용된다.
다음과 같이 exam에 대한 객체가 2개가 있다면 이때는 클래스뿐 아니라 변수명에 해당하는 id
를 비교하게 된다.
아래처럼 Exam 객체(를 구현한 NewlecExam 객체)를 DI하기 위해 명확하게 하려면
<!-- Exam exam = new NewlecExam(); -->
<bean id="exam2" class="spring.di.entity.NewlecExam" p:kor="10" p:eng="20"/>
<bean id="exam1" class="spring.di.entity.NewlecExam" p:kor="30" p:eng="40"/>
해당 소스코드에 @Qualifier를 추가한다. 이 때 id
값을 적어두어야 이를 익식하여 자동적으로 변수로 활용할 수 있게 된다.
@Autowired
@Qualifier("exam1")
@Override
public void setExam(Exam exam) {
this.exam = exam;
}