2021. 7. 9. 11:52ㆍJAVA/Spring
본 글은 최범균 저자의 초보 웹 개발자를 위한 스프링5 프로그래밍 입문 도서의 내용을 복습하기 위해 작성한 글입니다.
2. @Autowired 애노테이션을 이용한 의존 자동 주입
자동 주입 기능을 사용하면 스프링이 알아서 의존 객체를 찾아서 주입한다.
Before
@Bean
public MemberDao memberDao()
{
return new MemberDao();
}
@Bean
public ChangePasswordService changePwdSvc()
{
ChangePasswordService pwdSvc = new ChangePasswordService();
pwdSvc.setMemberDao(memberDao());
return pwdSvc;
}
자동 주입 기능을 사용하면 @Bean 메서드에서 의존을 주입하지 않아도 의존 객체가 아래와 같이 주입된다.
After
@Bean
public MemberDao memberDao()
{
return new MemberDao();
}
@Bean
public ChangePasswordService changePwdSvc()
{
ChangePasswordService pwdSvc = new ChangePasswordService();
return pwdSvc;
}
자동 의존 주입 기능 사용 방법
- 의존을 주입할 의존 객체 위에 @Autowired 애노테이션을 붙인다.
ChangePasswordService.java
public class ChangePasswordService {
@Autowired
private MemberDao memberDao;
public void changePassword(String email, String oldPwd, String newPwd)
{
Member member = memberDao.selectByEmail(email);
if(member==null)
{
throw new MemberNotFoundException();
}
member.changePassword(oldPwd, newPwd);
memberDao.update(member);
}
public void setMemberDao(MemberDao memberDao)
{
this.memberDao = memberDao;
}
}
필드에 @Autowired 애노테이션이 붙어있으면 스프링이 해당 타입의 빈 객체를 찾아서 필드에 할당한다.
AppCtx.java
@Configuration
public class AppCtx{
@Bean
public MemberDao memberDao()
{
return new MemberDao();
}
@Bean
public MemberRegisterService memberRegSvc()
{
return new MemberRegisterService(memberDao());
}
@Bean
public ChangePasswordService changePwdSvc()
{
ChangePasswordService pwdSvc = new ChangePasswordService();
// 의존을 주입하지 않아도 스프링이 @Autowired가 붙인 필드에
// 해당 타입의 빈 객체를 찾아서 주입한다.
return pwdSvc;
}
.. 생략
ChangePasswordService 클래스의 memberDao 필드에 @Autowired 애노테이션을 붙였으므로 스프링 설정 클래스인 AppCtx 클래스는 ChangePasswordService 객체를 생성시 따로 setter 메서드를 통해서 memberDao 객체를 의존주입하지 않아도 된다. 스프링이 MemberDao 타입의 빈 객체를 주입하기 때문이다.
실행결과
실행 결과 비밀번호 변경 기능이 수행된 것을 알 수 있다. 만약 @Autowired 애노테이션을 설정한 필드에 알맞은 빈 객체가 주입되지 않았따면 ChangePasswordService의 memberDao 필드는 null일 것이다. 하지만 정상 동작 했따는 것은 @Autowired 애노테이션을 붙인 필드에 실제 MemberDao 타입의 빈 객체가 주입되었음을 의미한다.
@Autowired 애노테이션을 메서드에 설정하는 경우
- 의존 객체 필드 멤버에 @Autowired 애노테이션을 적용하는 것과 같은 효과를 볼 수 있다.
MemberInfoPrinter.java
public class MemberInfoPrinter {
private MemberDao memDao;
private MemberPrinter printer;
public void printMemberInfo(String email)
{
Member member = memDao.selectByEmail(email);
if(member==null)
{
System.out.println("데이터 없음\n");
return;
}
printer.print(member);
System.out.println();
}
//변경점 setter 메서드에 @Autowired 설정
@Autowired
public void setMemDao(MemberDao memDao) {
this.memDao = memDao;
}
@Autowired
public void setPrinter(MemberPrinter printer) {
this.printer = printer;
}
}
AppCtx 설정 클래스에서 infoPrinter() 메서드를 아래와 같이 수정한다.
AppCtx.java
@Configuration
public class AppCtx{
@Bean
public MemberDao memberDao()
{
return new MemberDao();
}
... 생략
@Bean
public ChangePasswordService changePwdSvc()
{
ChangePasswordService pwdSvc = new ChangePasswordService();
// 의존을 주입하지 않아도 스프링이 @Autowired가 붙인 필드에
// 해당 타입의 빈 객체를 찾아서 주입한다.
return pwdSvc;
}
@Bean
public MemberPrinter memberPrinter()
{
return new MemberPrinter();
}
... 생략
@Bean
public MemberInfoPrinter infoPrinter()
{
MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
return infoPrinter;
}
... 생략
}
infoPrinter() 메서드에서 MemberInfoPrinter 객체의 두 세터 메서드를 호출하지 않도록 수정했다.
실행결과
빈 객체의 메서드에 @Autowired 애노테이션을 붙이면 스프링은 해당 메서드를 호출한다. 이때 메서드 파라미터 타입에 해당하는 빈 객체를 찾아 인자로 주입한다.
@Autowired 애노테이션과 빈의 매칭
@Autowired 애노테이션을 필드나 세터 메서드에 붙이면 스프링은 타입이 일치하는 빈 객체를 찾아서 주입한다.
ChangePasswordService의 memberDao 필드의 타입은 MemberDao이므로 일치하는 타입을 가진 memberDao 빈이 주입된다. 유사하게 MemberInfoPrinter의 setMemberDao() 메서드의 memberDao 파라미터 타입이 MemberDao 클래스 타입이므로 setMemberDao() 메서드에 일치하는 타입을 가진 memberDao 빈이 주입된다.
MemberRegisterService 클래스의 의존 객체에게 @Autowired 애노테이션 설정
MemberRegisterService.java
public class MemberRegisterService {
@Autowired
private MemberDao memberDao;
public MemberRegisterService()
{
}
public MemberRegisterService(MemberDao memberDao)
{
this.memberDao = memberDao;
}
public Long regist(RegisterRequest req)
{
Member member = memberDao.selectByEmail(req.getEmail());
if(member!=null)
{
throw new DuplicateMemberException("dup email " + req.getEmail());
}
Member newMember = new Member(
req.getEmail(),
req.getPassword(),
req.getName(),
LocalDateTime.now()
);
memberDao.insert(newMember);
return newMember.getId();
}
}
MemberListPrinter 클래스의 setter 메서드에 @Autowired 애노테이션 설정
public class MemberListPrinter {
private MemberDao memberDao;
private MemberPrinter printer;
public MemberListPrinter()
{
}
public MemberListPrinter(MemberDao memberDao, MemberPrinter printer)
{
this.memberDao = memberDao;
this.printer = printer;
}
public void printAll()
{
Collection<Member> members = memberDao.selectAll();
members.forEach(m->printer.print(m));
}
@Autowired
public void setMemberDao(MemberDao memberDao) {
this.memberDao = memberDao;
}
@Autowired
public void setPrinter(MemberPrinter printer) {
this.printer = printer;
}
}
AppCtx.java
@Configuration
public class AppCtx{
@Bean
public MemberDao memberDao()
{
return new MemberDao();
}
@Bean
public MemberRegisterService memberRegSvc()
{
return new MemberRegisterService();
}
@Bean
public ChangePasswordService changePwdSvc()
{
ChangePasswordService pwdSvc = new ChangePasswordService();
// 의존을 주입하지 않아도 스프링이 @Autowired가 붙인 필드에
// 해당 타입의 빈 객체를 찾아서 주입한다.
return pwdSvc;
}
@Bean
public MemberPrinter memberPrinter()
{
return new MemberPrinter();
}
@Bean
public MemberListPrinter listPrinter()
{
return new MemberListPrinter();
}
@Bean
public MemberInfoPrinter infoPrinter()
{
MemberInfoPrinter infoPrinter = new MemberInfoPrinter();
return infoPrinter;
}
@Bean
public VersionPrinter versionPrinter()
{
VersionPrinter versionPrinter = new VersionPrinter();
versionPrinter.setMajorVersion(5);
versionPrinter.setMinorVersion(0);
return versionPrinter;
}
}
실행결과
References
초보 웹 개발자를 위한 스프링5 프로그래밍 입문, 최범균 저
github, https://github.com/yonghwankim-dev/spring5
'JAVA > Spring' 카테고리의 다른 글
4. 의존 자동 주입 #3-2 @Qualifier 애노테이션 적용을 통한 특정 빈 설정 메소드 수행 확인 (0) | 2021.07.12 |
---|---|
4. 의존 자동 주입 #3-1 @Qualifier 애노테이션을 이용한 의존 객체 선택 (0) | 2021.07.09 |
4. 의존 자동 주입 #1 예제 프로젝트 준비 (0) | 2021.07.09 |
3. 스프링 DI(Dependency Injection) #6 getBean() 메서드 사용 (0) | 2021.07.09 |
3. 스프링 DI(Dependency Injection) #5 두 개 이상의 설정 파일 사용하기 (0) | 2021.07.06 |