๋ชฉ์ฐจ
์์กด์ฃผ์ ๋ฐฉ๋ฒ
์ค์ ํด๋์ค์์ ์ง์ ์์กด ์ฃผ์
์ค์ ํด๋์ค์์ ์์กด๊ฐ์ฒด๋ฅผ ์ง์ ์ฃผ์ ํด์ฃผ๋ ๋ฐฉ๋ฒ์ด๋ค.
@Configuration
public class AppCtx {
@Bean
public MemberDao memberDao(){
return new MemberDao();
}
@Bean
public MemberRegisterService memberRegisterService(){
return new MemberRegisterService(memberDao());
}
@Bean
public ChangePasswordService changePasswordService(){
ChangePasswordService changePasswordService = new ChangePasswordService();
changePasswordService.setMemberDao(memberDao());
return changePasswordService;
}
}
์๋ ์์กด ์ฃผ์
์ค์ ํด๋์ค์์ ์ง์ ์ฃผ์ ํ์ง ์๊ณ , ์คํ๋ง์ด ์๋์ผ๋ก ์์กด ๊ฐ์ฒด๋ฅผ ์ฃผ์ ํด์ฃผ๋ ๋ฐฉ๋ฒ์ด๋ค.
์ค์ ํด๋์ค์์ ์์ฑ์, setter๋ก memberDao๋ฅผ ์ฃผ์ ํด์ฃผ๋ ์ฝ๋๋ฅผ ๋ชจ๋ ์ฃผ์์ฒ๋ฆฌํ๋ค.
@Configuration
public class AppCtx {
@Bean
public MemberDao memberDao(){
return new MemberDao();
}
@Bean
public MemberRegisterService memberRegisterService(){
// return new MemberRegisterService(memberDao());
return new MemberRegisterService();
}
@Bean
public ChangePasswordService changePasswordService(){
ChangePasswordService changePasswordService = new ChangePasswordService();
// changePasswordService.setMemberDao(memberDao());
return changePasswordService;
}
}
์์กด์ ์ฃผ์ ๋ฐ๋ ํด๋์ค์์ ํ๋ ๋๋ Setter๋ฉ์๋์ @Autowired๋ฅผ ๋ถ์ธ๋ค.
(์ฌ๊ธฐ์ ์์ฑ์์ @Autowired๋ฅผ ๋ถ์ด๋ฉด AppCtx์์ @Bean์ ์์ฑํ ๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค. )
public class MemberRegisterService {
@Autowired //โญ
private MemberDao memberDao;
// constructor DI
// public MemberRegisterService(MemberDao memberDao) {
// this.memberDao = memberDao;
// }
public Long regist(RegisterDTO req){
//ํ์๊ฐ์
๋ก์ง
...
}
}
public class ChangePasswordService {
@Autowired //โญ
private MemberDao memberDao;
// @Autowired //โญ ์ฌ๊ธฐ์ ๋ถ์ฌ๋๋๋ค.
// public void setMemberDao(MemberDao memberDao) {
// this.memberDao = memberDao;
// }
public void changePassword(String email, String oldpwd, String newpwd){
//๋น๋ฐ๋ฒํธ ๋ณ๊ฒฝ๋ก์ง
...
}
}
@Autowired ์ด๋ ธํ ์ด์ ์ ํ๋๋ setter๋ฉ์๋์ ๋ถ์ด๋ฉด
์คํ๋ง ์ปจํ ์ด๋๋ ํ์ ์ด ์ผ์นํ๋ Bean๊ฐ์ฒด๋ฅผ ์ฐพ์ ์ฃผ์ ํด์ค๋ค.
@Autowired ์์กด ์ฃผ์ ์ ํ์ ์ผ์นํ๋ Bean์ด ์๋ ๊ฒฝ์ฐ
UnsatisfiedDependencyException ๋ฐ์
@Autowired ์์กด ์ฃผ์ ์ ํ์ ์ผ์นํ๋ Bean์ด 2๊ฐ ์ด์์ธ ๊ฒฝ์ฐ -> @Qualifier ์ด๋ ธํ ์ด์ ์ฌ์ฉ
@Configuration
public class AppCtx {
@Bean
public MemberDao memberDao1(){ //โญ
return new MemberDao();
}
@Bean
public MemberDao memberDao2(){ //โญ
return new MemberDao();
}
@Bean
public MemberRegisterService memberRegisterService(){
return new MemberRegisterService();
}
@Bean
public ChangePasswordService changePasswordService(){
return new ChangePasswordService();
}
}
public class MemberRegisterService {
@Autowired
private MemberDao memberDao;
...
}
public class ChangePasswordService {
@Autowired
private MemberDao memberDao;
...
}
๊ทธ๋ฅ ์คํํ๋ฉด NoUniqueBeanDefinitionException ๋ฐ์
@Qualifier๋ฅผ ์ฌ์ฉํ์ฌ ํด๊ฒฐํ ์ ์๋ค.
@Configuration
public class AppCtx {
@Bean
@Qualifier("memberDaoForRegister") //โญ
public MemberDao memberDao1(){
return new MemberDao();
}
@Bean
public MemberDao memberDao2(){
return new MemberDao();
}
@Bean
public MemberRegisterService memberRegisterService(){
return new MemberRegisterService();
}
@Bean
public ChangePasswordService changePasswordService(){
return new ChangePasswordService();
}
}
public class MemberRegisterService {
@Autowired
@Qualifier("memberDaoForRegister") //โญ
private MemberDao memberDao;
public Long regist(RegisterDTO req){
//ํ์๊ฐ์
๋ก์ง
}
}
AppCtx์ @Bean ๋ฑ๋ก ์ @Qualifier๋ก ์ด๋ฆ ์ง์ , @Autowired๋ก ๋น ์ฃผ์ ์ @Qualifier๋ก ์ด๋ฆ ์ง์
์์ชฝ์ ์ ์ด์ฃผ์ด์ ๋น์ ์ด๋ฆ์ผ๋ก ๊ตฌ๋ถํ๋ค.
(๋์ผ ํ์ ๋น์ด 2๊ฐ์ผ๋, ํ๋์๋ง Qualifier๋ฅผ ๋ถ์ฌ๋ ๋ ๋น์ ๊ตฌ๋ถํ ์ ์๊ธฐ ๋๋ฌธ์ ์ค๋ฅ์์ด ์คํ ๊ฐ๋ฅํ๋ค)
์์/ํ์ ํ์ ๊ด๊ณ์ ์๋์ฃผ์
public class MemberParentPrinter {
}
public class MemberChildPrinter extends MemberParentPrinter{
}
์์๊ด๊ณ์์ @Qualifier ์ ๋ ธํ ์ด์ ์ ์๋ถ์ธ๋ค๋ฉด ์ด๊ฒ๋ NoUniqueBeanDefinitionException์ด ๋ฐ์ํ๋ค.
@Autowired ํ์ ์ฌ๋ถ
@Autowired๋ ๊ธฐ๋ณธ์ ์ผ๋ก ํ์ ์ ํด๋นํ๋ ๋น์ด ์กด์ฌํ์ง ์์ผ๋ฉด Exception์ด ๋ฐ์ํ๋ค.
@Autowired(required = false)
public void setDateFormatter(DateTimeFormatter dateTimeFormatter){
this.dateTimeFormatter = dateTimeFormatter;
}
@Autowired
public void setDateFormatter(Optional<DateTimeFormatter> dateTimeFormatter){
this.dateTimeFormatter = dateTimeFormatter;
}
@Autowired
public void setDateFormatter(@Nullable DateTimeFormatter dateTimeFormatter){
this.dateTimeFormatter = dateTimeFormatter;
}
์๋ ์ฃผ์ ํ ๋์์ด ํ์๊ฐ ์๋ ๊ฒฝ์ฐ์๋
@Autowired ์ ๋ ธํ ์ด์ ์ required ์์ฑ์ false๋ก ์ง์ ํ๊ฑฐ๋,
Optional์ ์ฌ์ฉํ๊ฑฐ๋, @Nullable์ ์ฌ์ฉํ์ฌ ์๋์ฃผ์ ์ ์ํํ์ง ์์ผ๋ฉด๋๋ค.
์์ ๋ฐฉ์์ ํ๋์๋ ๊ทธ๋๋ก ์ ์ฉ๋๋ค.
@Autowired(required = false)
private DateTimeFormatter dateTimeFormatter;
@Autowired
private Optional<DateTimeFormatter> dateTimeFormatter;
@Autowired
@Nullable
private DateTimeFormatter dateTimeFormatter;
์์ฑ์ ์ด๊ธฐํ์ ํ์ ์ฌ๋ถ ์ง์
public class MemberPrinter{
private DateTimeFormatter dateTimeFormatter;
public MemberPrinter(){
dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy๋
MM์ dd์ผ");
}
@Autowired(required = false)
public void setDateTimeFormatter(DateTimeFormatter dateTimeFormatter){
this.dateTimeFormatter = dateTimeFormatter;
}
}
์์ ์ฝ๋๋ฅผ ์คํํ๋ฉด DateTimeFormatter๋ ๊ธฐ๋ณธ์์ฑ์์์ ์ด๊ธฐํ ๋ ๊ฐ("yyyy๋ MM์ dd์ผ")์ ์ฌ์ฉํ๋ค.
=> required = false๋ ๋งค์นญ๋๋ ๋น์ด ์๋ค๋ฉด ์๋ฌด๊ฒ๋ ํ์ง ์๋๋ค.
=> ๊ธฐ๋ณธ์์ฑ์์ ์ด๊ธฐํ ๊ฐ์ ๋ณ๊ฒฝํ์ง ์๋๋ค.
public class MemberPrinter{
private DateTimeFormatter dateTimeFormatter;
public MemberPrinter(){
dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy๋
MM์ dd์ผ");
}
@Autowired
public void setDateTimeFormatter(@Nullable DateTimeFormatter dateTimeFormatter){
this.dateTimeFormatter = dateTimeFormatter;
}
}
์์ ์ฝ๋๋ฅผ ์คํํ๋ฉด DateTimeFormatter๋ ๊ธฐ๋ณธ์์ฑ์๊ฐ ์๋ Setter์์ ์ค์ ๋ ๊ฐ์ ์ฌ์ฉํ๋ค.
=> @Nullable์ ๋งค์นญ๋๋ ๋น์ด ์๋ค๋ฉด ๊ฐ์ null๋ก ์ค์ ํ๋ค.
=> ๊ธฐ๋ณธ์์ฑ์์ ์ด๊ธฐํ ๊ฐ์ ์ค์ ํ ํ, Setter๋ฅผ ์คํํจ์ผ๋ก์จ null์ด ์ค์ ๋๋ค.
Optional๋ ๋ง์ฐฌ๊ฐ์ง๋ก Optional์ ํ ๋นํ๋ค.
์๋ ์ฃผ์ ๊ณผ ๋ช ์์ ์์กด ์ฃผ์
@Configuration
public class AppCtx{
@Bean @Qualifier("printer")
public MemberPrinter memberPrinter(){
return new MemberPrinter();
}
@Bean @Qualifier("summaryPrinter")
public MemberSummaryPrinter memberPrinter2(){
return new MemberSummaryPrinter();
}
@Bean
public MemberInfoPrinter infoPrinter(){
MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
//MemberInfoPrinter์ setPrinter๋ฉ์๋์๋ @Autowired๊ฐ ๋ถ์ด์์ด์
//memberPrinter(=MemberPrinter)๋ฅผ ์ค์ ํด์ค๋ค.
infoPrinter.setPrinter(memberPrinter2());
//๊ทธ ๋ค์ setter๋ก ๋ค์ memberPrinter2(=MemberSummaryPrinter)๋ฅผ ์ค์ ํด์ค๋ค.
}
}
public class MemberInfoPrinter{
@Autowired @Qualifier("printer")
public void setPrinter(MemberPrinter memberPrinter){
this.printer = memberPrinter;
}
}
๊ฒฐ๊ณผ๋ MemberPrinter์ ๋ด์ฉ์ผ๋ก ์คํ๋๋ค.
์ฆ, setter DI๋ก ์ธ๋ถ์์ ๊ฐ์ ๋ฃ์ด์ฃผ์ด๋
ํด๋น setter์ @Autowired๊ฐ ๋ถ์ด์์ผ๋ฉด @Autowired๊ฐ ์ฐ์ ๊ถ์ ๊ฐ๋๋ค.
์ฐ์ ์์ : @Autowired > Setter DI ์ฃผ์
์ ๋ฆฌ
• ์์กด ์ฃผ์
๋ฐฉ๋ฒ
- ์ง์ ์์กด์ฃผ์
: Bean์ ์์ฑํ ๋ setter๋ก ์์กด์ ์ฃผ์
ํ๋ ๋ฐฉ๋ฒ
- ์๋์์กด์ฃผ์
: Bean์ ์์ฑํ ๋ setter๋ฅผ ์ฌ์ฉํ์ง ์๊ณ ,
๊ฐ ํด๋์ค๋ค์ ํ๋/setter์ @Autowired๋ฅผ ๋ถ์ฌ์ ์์กด์ ์ฃผ์
ํ๋ ๋ฐฉ๋ฒ
• @Autowired๋ ํ์
์ด ์ผ์นํ๋ Bean๊ฐ์ฒด๋ฅผ ์ฐพ์ ์ฃผ์
ํด์ค๋ค.
ํ์
์ผ์น Bean์ด ์์ผ๋ฉด -> UnsatisfiedDependencyException ๋ฐ์
ํ์
์ผ์น Bean์ด 2๊ฐ ์ด์์ด๋ฉด -> NoUniqueBeanDefinitionException ๋ฐ์.
@Qualifier๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๊ฐ ๋น์ ์ด๋ฆ์ ์ง์ ํ์ฌ ํด๊ฒฐ ๊ฐ๋ฅ
• @Qualifier๋ฅผ ์ฌ์ฉํ๋ฉด ์ค์ ํด๋์ค์ ์ฃผ์
๋๋ ํด๋์ค์ ๋ชจ๋ ์ ์ด์ฃผ์ด์ผํ๋ค.
• ์์/ํ์ ํ์
๊ด๊ณ์์ @Qualifier๋ ์๋ถ์ด๋ฉด -> NoUniqueBeanDefinitionException ๋ฐ์. @Qualifier๋ก ํด๊ฒฐ ๊ฐ๋ฅ
• ์๋ ์ฃผ์
ํ ๋์์ด ํ์๊ฐ ์๋๋ฉด 3๊ฐ์ง ๋ฐฉ๋ฒ ์ฌ์ฉ
- @Autowired(required = false) : ๋งค์นญ๋๋ ๋น์ด ์๋ค๋ฉด ๊ฐ์ ํ ๋นํ์ง ์๋๋ค
- Optional : ๋งค์นญ๋๋ ๋น์ด ์์ผ๋ฉด Optional ํ ๋น
- @Nullable : ๋งค์นญ๋๋ ๋น์ด ์์ผ๋ฉด Null์ ํ ๋นํ๋ค.
• ์์กด ์ฃผ์
๋ฐ๋ ํด๋์ค์ setter์ @Autowired๊ฐ ์์ด์ A๋ฅผ ์ฃผ์
๋ฐ์ ์ ์๋๋ฐ
์ค์ ํด๋์ค์์ setter๋ฅผ ํธ์ถํด B๋ฅผ ์ฃผ์
ํด์ฃผ๋ฉด?
@Autowired๊ฐ setter DI๋ณด๋ค ์ฐ์ ์์๊ฐ ๋๊ธฐ๋๋ฌธ์ A๋ก ๋์ํ๊ฒ๋๋ค.