[Spring] @Autowired annotation 사용법
[Spring] p 네임스페이스, c 네임스페이스란? + ref 사용법
지난 포스팅에서는 p 네임스페이스와 ref를 사용하여 Bean에 DAO 등을 주입하는 방법을 알아보았다.
오늘은 @Autowired 어느테이션을 사용하여
p:[Dao name]-ref="daoName"
과 같은 특성을 더 이상 사용하지 않는 방법을 알아보도록 할 것이다.
@Autowired를 사용할 수 있는 위치는 아래와 같이 세 가지가 있다.
- 생성자
- Setter
- 필드
각각의 방식에서 @Autowired를 사용할 수 있는 방법을 알아보도록 하자.
1. 생성자에 @Autowired를 사용하는 방법
@Service
public class AccountService {
AccountDao accountDao;
@Autowired
public AccountService(AccountDao accountDao){
this.accountDao=accountDao;
}
}
위와 같은 accountService class가 하나 있다고 가정해보자.
위의 @Autowired가 적용되기 위해서 AccountDao class는 어떤 형태를 띄어야 할까?
public class AccountDao {
//
}
단순히 위와 같은 class로 짜여있으면 작동하지 않을 것이다.
@Repository
public class AccountDao {
//
}
위와 같이 @Repository annotation이 존재해야 작동하는데, 그 이유는 @Autowired가 의존 객체 type의 bean들을 찾아서 주입해주기 때문이다. @Repository annotation이 없으면 AccountDao를 bean으로 인식하지 못하여 의존성 주입에 실패하게 된다.
2. Setter에 @Autowired를 사용하는 방법
@Service
public class AccountService {
AccountDao accountDao;
@Autowired(required = false)
public void setAccountDao(AccountDao accountDao) {
this.accountDao = accountDao;
}
}
public class AccountDao {
//
}
두 번째 방법은 위와 같이 setter method에 @Autowired annotation을 사용해주는 방법이다.
여기서
@Autowired(required = false)
위와 같이 required = false 옵션을 추가로 주게 되면 해당 bean이 없을 경우 주입받지 않을 수 있다는 뜻을 가진다. 만약 뒤에 required = false를 쓰지 않으면 기본값은 true 를 가진다. 즉 만약 requred = false가 추가로 들어가게 되면 해당 bean (여기서는 AccountDao) 이 호출조차 되지 않는다고 보면 된다.
3. 필드에 @Autowired 를 명시하는 방법
@Service
public class AccountService {
@Autowired
AccountDao accountDao;
}
위와 같이 필드 자체에 @Autowired annotation을 사용하는 방법도 있다.
여기서 만약 해당하는 형태의 Bean이 여러 개이면 어떻게 될까? 즉 만약 위와 같은 AccountService에서 Autowired로 연결된 AccountDao Bean이 여러 종류일 경우를 가정해보자.
public interface AccountDao {
//AccountDao interface
}
@Repository
public class FirstAccountDao implements AccountDao {
//
}
@Repository
public class SecondAccountDao implements AccountDao {
//
}
즉 위와 같이 AccountDao interface가 하나 존재하고 해당 인터페이스를 여러 Bean에서 객체로 구현을 할 경우이다. 여기서 FirstAccountDao, SecondAccountDao 모두 @Repository annotation이 있어, 둘 다 Bean으로 등록되어 있는 상황이다.
이런 상황에서 AccountService class에서 아래와 같이
@Service
public class AccountService {
@Autowired
AccountDao accountDao;
}
AccountDao Bean을 @Autowired로 연결하면 어떤 AccountDao가 연결이 될까?
이 경우 스프링에서는 에러를 뱉는다.
왜냐하면 연결되는 Bean을 찾는데 두 개 이상이 나오게 되면 어떤 의존성을 주입해야 하는지 스프링에서는 알 길이 없기 때문이다.