의존성 주입에 대한 의문은 다음 코드에서 생겼다!
@Inject
private BoardDAO dao;
serviceImpl 클래스에서 BoardDAO의 객체를 다음과같이 생성했다. 그런데 VO객체는 service,dao가 root-context.xml에, controller가 servlet-context.xml에 등록되는것과 다르게 아무곳에도 얘를 봐주세요~ 하는 표시가 없고, @Controller, @Repository, @Service같은 어노테이션도 붙어있지 않다. 그럼 어떻게 찾아서 객체를 생성하는걸까?
감으로 찍으면 다음과 같은 방법일것같다.
DAO
interface & DAOImpl
class 만들어두고 @Inject
로 DAO
의 새 인스턴스를 생성할때 DAO
라는 타입에 해당하는 클래스가 DAOImpl
하나밖에 없으니까 저걸로 생성된것만약 DAO인터페이스를 여러 클래스가 implement하면 그중 뭐쓸지 모르는거니까 오류 나는거고~
그렇다면 명확한 이유는 무엇일까? 내가 예상한게 맞을까?
의존성을 주입하는 어노테이션은 3가지가 있다.
1. @Autowired
2. @Resource
3. @Inject
순서대로 살펴보자
주입하려고 하는 객체의 타입이 일치하는 객체를 자동 주입
단 @Autowired는 필드, 생성자, Setter에 붙일수있다.
단, 필드, Setter에 붙여 쓸경우 반드시 기본생성자가 정의되어있어야 한다.
필드, 생성자, Setter 주입 예시를 살펴보자
public class 필드주입예시 {
@Autowired
private WordDao wordDao;
public WordRegisterServiceUseAutowired() { }
}
public class 생성자주입예시 {
private WordDao wordDao;
@Autowired
public WordRegisterServiceUseAutowired(WordDao wordDao) {
this.wordDao = wordDao;
}
}
public class 세터주입예시 {
private WordDao wordDao;
public WordRegisterServiceUseAutowired() { }
@Autowired
public void setWordDao(WordDao wordDao) {
this.wordDao = wordDao;
}
}
<bean id="wordDao1" class="com.word.dao.WordDao" >
<qualifier value="usedDao"/>
</bean>
<bean id="wordDao2" class="com.word.dao.WordDao" />
<bean id="wordDao3" class="com.word.dao.WordDao" />
이처럼 동일타입의 빈 객체가 여러개 정의되어있을경우 우선적으로 사용할 빈 객체의 태그에 태그를 설정한다.
public class WordRegisterServiceUseAutowired {
@Autowired
@Qualifier("usedDao")
private WordDao wordDao;
public WordRegisterServiceUseAutowired() { }
}
자바에서는 @Autowired
와 함께 @Qualifier
를 사용해서 XML파일에서 설정한 value값을 지정해준다. 이러면 동일타입 빈이 여러개여도 우선적으로 특정 빈이 주입된다.
주입하려고 하는 객체의 이름(id)이 일치하는 객체를 자동으로 주입
자바에서 제공하는 어노테이션이며 필드, Setter에 붙일 수 있다. 생성자엔 불가능하다. 기본생성자가 정의되어있어야한다.
프로젝트에서 사용하고싶으면 의존성을 추가해야한다
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
import javax.annotation.Resource;
public class 필드주입 {
@Resource
private WordDao wordDao;
public WordRegisterServiceUseResource() { }
}
import javax.annotation.Resource;
public class 세터주입 {
private WordDao wordDao;
public WordRegisterServiceUseResource() { }
@Resource
public WordRegisterServiceUseResource(WordDao wordDao) {
this.wordDao = wordDao;
}
}
@Autowired와 유사하게 주입하려는 객체의 타입이 일치하는 객체를 자동으로 주입
Java제공 어노테이션이며 필드, 생성자, Setter에 붙일 수 있다. 필드, setter에 사용할경우 기본생성자가 정의되어있어야한다.
import javax.inject.Inject;
public class 필드주입 {
@Inject
private WordDao wordDao;
public WordRegisterServiceUseAutowired() { }
}
import javax.inject.Inject;
public class 생성자주입 {
private WordDao wordDao;
@Inject
public WordRegisterServiceUseAutowired(WordDao wordDao) {
this.wordDao = wordDao;
}
}
import javax.inject.Inject;
public class 세터주입 {
private WordDao wordDao;
public WordRegisterServiceUseAutowired() { }
@Inject
public void setWordDao(WordDao wordDao) {
this.wordDao = wordDao;
}
}
@Autowired에 @Qualifier가 있었듯 @Inject엔 @Named가 있다. @Qualifier와 달리 @Named는 빈이름(id)를 지정하므로 xml설정파일이 다소 짧아진다.
<bean id="wordDao1" class="com.word.dao.WordDao"/>
<bean id="wordDao2" class="com.word.dao.WordDao"/>
<bean id="wordDao3" class="com.word.dao.WordDao"/>
xml파일에 추가할게 없음
import javax.inject.Inject;
import javax.inject.Named;
public class WordRegisterServiceUseInject {
@Inject
@Named("wordDao1")
private WordDao wordDao;
public WordRegisterServiceUseInject() {
}
}