자동으로 필드에 할당
해 주는 기능@Autowired
와 @Resource
어노테이션 두 가지 방법이 존재
MVC
관점에서
Component는@Resource
를
Service는@Autowired
를 주로 사용하는 추세라고 함
// ChangePasswordService.java
public class ChangePasswordService {
@Autowired
private MemberDao memberDao;
...
public void setMemberDao(MemberDao memberDao) {
this.memberDao = memberDao;
}
}
//AppCtx.java
@Configuration
public class AppCtx {
@Bean
public MemberDao memberDao() {
return new MemberDao();
}
@Bean
public MemberRegisterService memberRegSvc() {
return new MemberRegisterService();
}
// 아래 함수에서 의존을 주입하지 않아도 스프링이 @Autowired가 붙인 필드에
// 해당 타입의 Bean 객체를 찾아서 주입
@Bean
public ChangePasswordService changePwdSvc() {
return new ChangePasswordService();
}
/* 기존 코드
@Bean
public ChangePasswordService changePwdSvc() {
ChangePasswordService pwdSvc = new ChangePasswordService();
pwdSvc.setMemberDao(memberDao());
return pwdSvc;
}
*/
...
}
넘겨주지 않음
// MemberInfoPrinter.java
public class MemberInfoPrinter {
private MemberDao memDao;
private MemberPrinter printer;
...
@Autowired
public void setMemberDao(MemberDao memberDao) {
this.memDao = memberDao;
}
@Autowired
public void setPrinter(MemberPrinter printer) {
this.printer = printer;
}
}
//AppCtx.java
@Configuration
public class AppCtx {
@Bean
public MemberDao memberDao() {
return new MemberDao();
}
...
// 원래 호출하던 두 매서드 setPrinter(), setMemberDao()를 호출하지 않음
@Bean
public MemberInfoPrinter infoPrinter() {
MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
return infoPrinter;
}
/* 기존코드
@Bean
public MemberInfoPrinter infoPrinter() {
MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
infoPrinter.setMemberDao(memberDao());
infoPrinter.setPrinter(memberPrinter());
return infoPrinter;
}
*/
...
}
@Autowired
어노테이션을 필드나 매서드에 붙이게 되면, 스프링은 타입이 일치하는 Bean 객체를 찾아서 주입
- 최근에는 위와 같은 방법이 권장
// AppCtx.java
@Configuration
public class AppCtx {
@Bean
public MemberDao memberDao() {
return new MemberDao();
}
...
// memberPrinter1() 매서드의 Bean의 한정 값으로 "printer"를 지정
@Bean
@Qualifier("printer")
public MemberPrinter memberPrinter1() {
return new MemberPrinter();
}
@Bean
public MemberPrinter memberPrinter2() {
return new MemberPrinter();
}
...
}
// MemberListPrinter.java
public class MemberListPrinter {
private MemberDao memberDao;
private MemberPrinter printer;
...
@Autowired
// 앞서 스프링 설정 클래스에서 @Qualifier 어노테이션의 값으로 "printer"를 준
// MembeerPrinter 타입의 Bean(memberPrinter1)을 자동 주입 대상으로 사용
@Qualifier("printer")
public void setMemberPrinter(MemberPrinter printer) {
this.printer = printer;
}
}
@Qualifier
어노테이션을 통해 자동 주입 Bean을 지정할 수 있음@Qualifier
어노테이션이 없다면, Bean의 이름
을 한정자로 지정자동 주입할 대상이 필수가 아닌 경우(NULL값 등) 아래와 같이 세가지 방법이 존재
@Autowired(required = false)
어노테이션 사용Optional 지정
@Nullable
어노테이션 사용// MemberPrinter.java
public class MemberPrinter {
private DateTimeFormatter dateTimeFormatter;
...
// 차례대로 1~3번 방법의 동일 매서드 코드
// 1번 방법
@Autowired(required = false)
public void setDateFormatter(DateTimeFormatter dateTimeFormatter) {
this.dateTimeFormatter = dateTimeFormatter;
}
// 2번 방법
@Autowired
public void setDateFormatter(Optional<DateTimeFormatter> dateTimeFormatter) {
this.dateTimeFormatter = dateTimeFormatter;
}
// 3번 방법
@Autowired
public void setDateFormatter(@Nullable DateTimeFormatter dateTimeFormatter) {
this.dateTimeFormatter = dateTimeFormatter;
}
각 방법의 특징은 아래와 같음
1. 매칭되는 Bean이 없어도 Exception이 발생하지 않으며 자동 주입을 수행하지 않음
2. 일치하는 Bean이 존재하지 않으면 값이 없는 Optional을 인자로 전달
(Exception 발생하지 않음),
일치하는 Bean이 존재하면 해당 Bean을 값으로 갖는 Optional을 인자로 전달
3. 스프링 컨테이너는 setter 매서드를 호출할 때 자동 주입할 Bean이 존재하면 해당 빈을 인자로 전달,
존재하지 않으면 인자로 NULL을 전달
매서드를 실행하지 않지만
,해당 매서드를 실행
함