Dependency Injection
특정 Bean의 기능 수행을 위해 다른 Bean을 참조해야 하는 경우 사용하는 Annotation으로는 @Autowired 또는 @Resource가 있다.
- @Autowired
Spring Framework에서 지원하는 Dependency 정의 용도의 Annotation으로, Spring Framework에 종속적이긴 하지만
정밀한 Dependency Injection이 필요한 경우에 유용하다.
- @Resource
JSR-250 표준 Annotation으로 Spring Framework 2.5.* 부터 지원 가능한 Annotation이다.
Annotation 사용으로 인해 특정 Framework에 종속적인 어플리케이션을 구성하지 않기 위해서는 @Resource를 사용할 것을 권장한다.
@Resource를 사용하기 위해서는 클래스패스 내에 jsr250-api.jar 파일이 추가되어야 함에 유의해야 한다.
@Service
public UserServiceImpl implements UserService {
@Resource
private UserDAO userDAO;
}
@Autowired, @Resource는 setter, 일반 메소드, 멤버 변수 또는 생성자에 정의 가능하며, 멤버 변수에 직접 정의하는 경우 별도 setter 정의는 불필요하다.
참조되는 Bean은 변수명을 Bean Name으로 하여 Spring 컨테이너에 의해 자동으로 인지되는데, 변수명을 이용하여 참조 관계에 놓인 Bean을 찾았는데 해당 Bean이 없는 경우에는
클래스 타입을 이용하게 된다.
기본적으로 @Autowired로 표시된 항목은 필수인 것으로 처리되나 required 옵션을 false로 하는 경우에는
해당되는 Bean을 못 찾아도 그냥 넘어간다.
@Service
public UserService implements UserService {
@Autowired(required=false)
private UserDAO userDAO;
}
Naming Auto Wired Dependencies
참조 관계에 놓인 Bean의 Name을 직접 명시하고자 하는 경우에는 다음과 같이 속성을 부여할 수 있다.
@Service
public UserServiceImpl implements UserService {
@Resource (name="uDAO")
private UserDAO userDAO;
}
@Autowired를 사용한 경우에는
@Qualifier를 사용하면 Bean Name으로 참조 관계 정의가 가능하다.
@Service
public UserServiceImpl implements UserService {
@Autowired
@Qualifier("uDAO")
private UserDAO userDAO;
}
Custom Qualifier
Annotation을 이용하여 보다 정밀하게 Dependency Injection을 수행할 필요가 있을 경우, Spring Framework의 Custom Qualifier를 사용할 수 있다.
- Custom Qualifier 정의
다음은 @UserDAOQualifier라는 Custom Qualifier 코드의 일부로 @UserDAOQualifier는 dbtype이라는 속성 정보를 갖고 있다.
dbtype 따라 참조해야 할 Bean이 달라지는 경우 즉, DBMS 유형에 따라 다른 데이터 접근 로직이 실행되어야 하는 경우에 사용될 수 있다.
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention (RetentionPolicy.RUNTIME)
@Qualifier
public @interface UserDAOQualifier {
String dbtype();
}
java.lang.annotation.Target은 사용한 Annotation이 어디에 적용될 것인지 Annotation을 선언할 때 정의한다.
(예를 들면 클래스나 메소드, 필드 등.) 만약 Target이 정해지지 않으면 어디에서나 사용가능한 Annotation이 된다.
java.lang.annotation.Retention은 Annotation을 선언할때 쓰이는데, 다음과 같은 Parameter들이 사용 가능하다.
- RetentionPolicy.SOURCE : 해당 Annotation이 소스레벨이라는 사실을 알려줌 (default)
- RetentionPolicy.CLASS : 소스코드와 컴파일된 클래스 파일에는 사용 가능하지만, 런타임에는 사용 불가.
- RetentionPolicy.RUNTIME : 소스코드, 컴파일된 코드, 런타임에도 사용 가능
- XML 정의
속성 정의 XML 파일 내에 Custom Qualifer로써 UserDAOQualifier 클래스에 대해 정의하여 특정 클래스에서 해당 Annotation을 사용할 수 있도록 한다.
<bean id="customAutowireConfigurer"
class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
<property name="customQualifierTypes">
<set><value>…UserDAOQualifier</value></set>
</property>
</bean>
다음은 dbtype에 따라 어떤 Bean이 할당될 것인지를 명시하는 부분으로 dbtype이 Oracle일 경우 UserDAOWIthOracle의 인스턴스가 컨테이너에 의해
인지되도록 정의되어 있음을 알 수 있다.
<bean class="...UserDAOWIthOracle">
<meta key="dbtype" value="oracle"/>
</bean>
- 활용
앞서 정의한 Custom Qualifier @UserDAOQualifier는 다음과 같이 사용한다. 다음의 코드에서 dbtype을 oracle로 정의하고 있으므로,
xml 정의에 따라 userDAO라는 변수에는 UserDAOWIthOracle의 인스턴스가 할당될 것이다.
public class UserServiceImpl implements UserService {
@Autowired
@UserDAOQualifier(dbtype="oracle")
private UserDAO userDAO;
// ...
}