어노테이션은 코드의 메타데이터를 설정해주는 자바의 기능이다 xml을 사용하는 방식에서 더 쉽게 DI를 적용하기 위해 어노테이션을 활용하여 DI를 구현하게 되었고 @Autowired를 사용한다.
@Autowired
Xml 파일로 DI 를 지시할 떄 사용했던 <property>를 대신한다.
의존객체의 setter 메서드에 명시해놓으면 <property>에 적어놓지 않아도 스프링이 알아서 의존객체를 찾아 주입해준다.
xml namespace에 context를 체크하고 아래의 코드를 추가 해줘야 한다.
<!-- 어노테이션 기반으로된 config임을 선언함 -->
<context:annotation-config/>
Autowired를 사용한 DI
public class GridExamConsole implements ExamConsole {
private Exam exam;
public GridExamConsole(Exam exam) {
this.exam = exam;
}
@Override
public void print() {
System.out.println("total | avg");
System.out.printf("%3d | %3.2f\n",exam.total(),exam.avg());
}
@Autowired
@Override
public void setExam(Exam exam) {
this.exam = exam;
}
}
위처럼 의존객체 setter 메서드에 @Autowired를 명시하면 객체생성시 @Autowired 어노테이션을 보고 스프링이 자동으로 의존 객체를 생성 하고 주입해 준다.
@Autowired의 동작 방식
Autowired는 클래스 타입을 기준으로 동작한다. 위의 예제 코드처럼 setExam이라는 의존객체 주입 메서드에 @Autowired가 붙어 있다면 IoC 컨테이너에서 우선 타입이 Exam인 bean을 찾아내서 주입해준다.
만약 같은 타입으로 등록된 bean이 여러개라면 다음으로는 주입 받는 변수명과 bean의 id를 비교하여 주입한다.
만약 변수명도 모호하다면 @Qualifier("bean의 id")를 사용하여 bean의 id를 지정해 줄 수있다.
//생성하는 객체의 의존객체 주입 setter 메서드
@Autowired
@Override
public void setExam(Exam exam) {
this.exam = exam;
}
//아래와 같이 bean의 클래스 타입이 같을 경우 bean의 아이디와 setter메서드의 변수명 비교
//첫번째 것이 주입된다.
<bean id="exam" class="src.spring.di.entity.NewlecExam" p:kor="20" p:eng="30" p:com="30" p:math="40"/>
<bean class="src.spring.di.entity.NewlecExam" p:kor="10" p:eng="20" p:com="40" p:math="50"/>
//bean의 아이디명도 모호할 경우
<bean id="exam1" class="src.spring.di.entity.NewlecExam" p:kor="20" p:eng="30" p:com="30" p:math="40"/>
<bean id="exam2" class="src.spring.di.entity.NewlecExam" p:kor="10" p:eng="20" p:com="40" p:math="50"/>
//@Qualifier("bean의 id")로 주입객체를 지정할 수 있다.
@Autowired
@Qualifier("exam1")
@Override
public void setExam(Exam exam) {
this.exam = exam;
}
인젝션의 3가지 방법
public class GridExamConsole implements ExamConsole {
1.
@Autowired <---기본생성자를 통한 DI
private Exam exam;
2.
@Autowired <---생성자를 통한 DI
public GridExamConsole(Exam exam) {
this.exam = exam;
}
@Override
public void print() {
System.out.println("total | avg");
System.out.printf("%3d | %3.2f\n",exam.total(),exam.avg());
}
3.
@Autowired <---setter를 통한 DI
@Override
public void setExam(Exam exam) {
this.exam = exam;
}
}
1.기본생성자를 통한 DI
2.생성자를 통한 DI
-생성자의 파라미터가 여러개가 될 수 있음으로 @Qualifier를 파라미터에 직접 적어줘야 한다.
3.setter를 통한 DI
@Autowired의 required 속성
@Autowired를 통해 주입 객체를 찾지 못하는 경우 bean으로 존재하지 않는 경우 에러가 나게된다.
null 일 경우를 대비하여 @Autowired(required = false)로 지정해놓으면 찾는 의존 객체가 없을 경우에도 객체가 생성된다
public class InlineExamConsole implements ExamConsole {
@Autowired(required = false)
@Qualifier("exam1")
private Exam exam;
public InlineExamConsole() {
}
public InlineExamConsole(Exam exam) {
this.exam = exam;
}
@Override
public void print() {
if(exam == null) {
System.out.println("의존객체가 없습니다.");
}else {
System.out.printf("total is %d, avg is %f\n",exam.total(),exam.avg());
}
}
@Override
public void setExam(Exam exam) {
this.exam = exam;
}
}
위 코드처럼 required = false로 해두면는 의존객체가 없을때에도 대처가 가능하다.
'SPRING FRAMEWORK' 카테고리의 다른 글
Spring core 스터디 3 - IoC 컨테이너 와 Application context (0) | 2021.04.06 |
---|---|
Spring core 스터디 1 - spring framework이란? (0) | 2021.04.03 |