[14강] @Autowired의 위치와 Required 옵션
1. 기본 형식
public class InlineExamConsole implements ExamConsole
{
private Exam exam;
public InlineExamConsole(){
System.out.println("constructor");
}
public InlineExamConsole(Exam exam){
System.out.println("overloaded constructor");
this.exam=exam;
}
@Override
public void setExam(Exam exam){
System.out.println("setter");
this.exam=exam;
}
@Override
public void print(){
System.out.printf("total is %d, avg is %f\n",exam.total(), exam.avg());
}
}
여기서 Annotation을 사용하여 객체를 주입하기 위해서 @Autowired가 들어갈 수 있는 자리는 총 4군대로
변수 exam 앞, 기본 생성자 앞, 오버라이드된 생성자 앞, 세터 앞이다.
<!--pom.xml-->
<bean id="exam1" class="sprint.di.entity.NewLecExam" p:kor="10" p:eng="10"/>
<bean id="exam2" class="sprint.di.entity.NewLecExam" p:kor="20" p:eng="20"/>
xml 파일에 위와같은 빈 객체들이 입력된 상테에서 진행된다.
2. setter 앞에 @Autowired 어노테이션을 붙인 경우
private Exam exam;
public InlineExamConsole(){
System.out.println("constructor");
}
public InlineExamConsole(Exam exam){
System.out.println("overloaded constructor");
this.exam=exam;
}
@Autowired
@Qualifier("exam2")
public void setExam(Exam exam){
System.out.println("setter");
this.exam=exam;
}
위 같이 setter 앞에 @Autowired가 붙는다면 먼저 기본생성자를 통해 객체를 생성하고 setter가 실행되기 때문에
constructor
setter
라는 결과가 출력된다.
이 때 만약 기본생성자가 작성되어 있지 않다면 오류가 발생한다.
기본 생성자를 작성하지 않고도 오류가 발생하지 않으려면 오버라이드된 생성자를 작성하지 않아야 한다.
그래야 컴파일러가 자동으로 기본 생성자를 생성해낼 것이기 때문이다.
3. 변수 앞에 @Autowired 어노테이션을 붙인 경우
@Autowired
@Qualifier("exam2")
private Exam exam;
public InlineExamConsole(){
System.out.println("constructor");
}
public InlineExamConsole(Exam exam){
System.out.println("overloaded constructor");
this.exam=exam;
}
public void setExam(Exam exam){
System.out.println("setter");
this.exam=exam;
}
construct
라는 결과가 출력된다.
setter가 실행되지 않고 해당 변수에 객체만을 주입하기 때문이다.
4. 오버라이드된 생성자에 @Autowired 어노테이션을 붙인 경우
private Exam exam;
public InlineExamConsole(){
System.out.println("constructor");
}
@Autowired
public InlineExamConsole(
@Qualifier("exam1") Exam exam1,
@Qualifier("exam2") Exam exam2){
System.out.println("overloaded constructor");
this.exam=exam1;
}
public void setExam(Exam exam){
System.out.println("setter");
this.exam=exam;
}
오버라이드된 생성자에는 1개 이상의 매개변수가 들어오기 때문에, 각각의 매개변수에 특정 이름을 명시하는
@Qualifier가 필요하다.
같은 타입의 매개변수가 여러개 입력될 수도 있기 때문이다.
overloaded constructor
setter는 실행되지않으며 출력값을 위와 같다.
5. @Autowired(required = false)
그런데 xml 파일에 baen 객체가 입력되지 않은 경우에는 위 코드들에서 오류가 발생한다.
이를 막기 위해서는 어떻게 해야할까?
Autowired에 required= false를 적용시키면 이를 해소시킬 수 있다.
public class InlineExamConsole implements ExamConsole
{
@Autowired(required=false)
@Qualifier("exam2")
private Exam exam;
public InlineExamConsole(){
System.out.println("constructor");
}
public InlineExamConsole(Exam exam){
System.out.println("overloaded constructor");
this.exam=exam;
}
@Override
public void setExam(Exam exam){
System.out.println("setter");
this.exam=exam;
}
@Override
public void print(){
if(exam==null)
System.out.printf("total is %d, avg is %f\n",0, 0);
else
System.out.printf("total is %d, avg is %f\n",exam.total(), exam.avg());
}
}
만약 xml에 해당하는 객체가 없는 경우, exam은 null값을 갖게되며 오류가 발생하지 않는다.
위처럼 print 함수 호출 시에 다른 분기를 만들어 낼 수도 있다.