8월 30, 2023

[Spring] @Autowired annotation 사용법

[Spring] p 네임스페이스, c 네임스페이스란? + ref 사용법

 

지난 포스팅에서는 p 네임스페이스와 ref를 사용하여 Bean에 DAO 등을 주입하는 방법을 알아보았다. 

오늘은 @Autowired 어느테이션을 사용하여 

p:[Dao name]-ref="daoName"

과 같은 특성을 더 이상 사용하지 않는 방법을 알아보도록 할 것이다. 


@Autowired를 사용할 수 있는 위치는 아래와 같이 세 가지가 있다.

  1. 생성자
  2. Setter
  3. 필드

각각의 방식에서 @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을 찾는데 두 개 이상이 나오게 되면 어떤 의존성을 주입해야 하는지 스프링에서는 알 길이 없기 때문이다.