티스토리 뷰
각 클래스를 생성하고, 이를 bean 객체로 등록하는 것이 조금 번거로운 작업이라고 생각할 수 있다.
이번 포스팅은 클래스를 생성하고, @Component 어노테이션을 다는 것만으로 bean 객체를 자동 등록할 수 있는 기법인 component-scan 을 다루려고 한다.
우선, component-scan은 context Namespace의 하나로, 다음과 같이 Namespace 탭에서 context를 선택하여 추가해야 한다.
Namespace를 등록했으면, xml 설정 파일에 이전에 등록했던 bean 객체를 전부 주석처리 한 다음, 아래와 같이 component-scan을 등록해주기만 하면 xml 파일 작성은 끝이 난다.
◎applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- component-scan -->
<context:component-scan base-package="polymorphism"></context:component-scan>
</beans>
이렇게 설정하면 polymorphism 패키지 내부에 모든 소스에 대하여 scan이 들어가며, bean 객체로 등록할 클래스에 다음과 같은 어노테이션만 작성해주면, 굳이 xml 문서 내부에 bean 태그를 이용하여 등록하지 않아도 자동으로 등록이 완료된다.
◎SamsungTV
package polymorphism;
import org.springframework.stereotype.Component;
@Component("tv")
public class SamsungTV implements TV{
public SamsungTV() {
System.out.println("SamsungTV --- 객체 생성");
}
@Override
public void powerOn() {
System.out.println("SamsungTV --- 전원 켜기");
}
@Override
public void powerOff() {
System.out.println("SamsungTV --- 전원 끄기");
}
}
의존성 주입:
지난 예제들과 같이 SamsungTV에 Speaker라는 맴버 객체를 주입하고 싶다면, 다음의 어노테이션들을 사용하여 따로 xml 파일을 수정하지 않고 주입할 수 있다.
- @Autowired:
주입할 맴버 변수 상단에 작성하면, 해당 객체가 사용되는 지점에서 프로젝트가 자동으로 Autowired어노테이션이 붙은 객체를 찾아 사용한다.
◎SamsungTV
package polymorphism;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component("tv")
public class SamsungTV implements TV{
@Autowired
private Speaker speaker;
private int price = 0;
public SamsungTV() {
System.out.println("SamsungTV --- 객체 생성");
}
public void setSpeaker(Speaker speaker) {
System.out.println("setSpeaker");
this.speaker = speaker;
}
public void setPrice(int price) {
System.out.println("setPrice");
this.price = price;
}
@Override
public void powerOn() {
System.out.println("SamsungTV --- 전원 켜기");
}
@Override
public void powerOff() {
System.out.println("SamsungTV --- 전원 끄기");
}
@Override
public void volumeUp() {
//System.out.println("SamsungTV --- 볼륨 켜기");
speaker.volumeUp();
System.out.println(this.price);
}
@Override
public void volumeDown() {
//System.out.println("SamsungTV --- 볼륨 줄이기");
speaker.volumeDown();
}
}
그러나, 이 @Autowired 어노테이션을 사용하기 위해서는 반드시 해당 객체가 bean객체로 선언이 되어 있어야 하기 때문에, 아래 두 방법 중 하나를 선택해서 객체를 등록해야한다.
1. ◎applicationContext.xml에 등록
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- component-scan -->
<context:component-scan base-package="polymorphism"></context:component-scan>
<bean id = "sony" class = "polymorphism.SonySpeaker"></bean>
</beans>
2. ◎SonySpeaker에 등록
package polymorphism;
import org.springframework.stereotype.Component;
@Component("sony")
public class SonySpeaker implements Speaker {
public SonySpeaker() {
System.out.println("==> SonySpeaker 객체 생성");
}
/* (non-Javadoc)
* @see polymorphism.Speaker#volumeUp()
*/
@Override
public void volumeUp() {
System.out.println("SonySpeaker --- 볼륨 켜기");
}
/* (non-Javadoc)
* @see polymorphism.Speaker#volumeDown()
*/
@Override
public void volumeDown() {
System.out.println("SonySpeaker --- 볼륨 줄이기");
}
}
- @Qualifier:
Spring container 내에 동일한 타입을 갖는 객체가 여러 개일 경우 사용한다.
만약에 위 예제에서 sony 스피커 이외에 Speaker 인터페이스를 구현받는 또 하나의 스피커, apple 스피커가 있다고 가정하면, Spring Container는 Autowired만으로는 둘을 구분하지 못한다.
이때 Qualifier를 사용하면 각 객체에 이름을 지정해줄 수 있기 때문에, 쉽게 구별할 수 있도록 만들 수 있다.
해당 어노테이션은 다음과 같이 사용한다.
◎SamsungTV
package polymorphism;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component("tv")
public class SamsungTV implements TV{
@Autowired
@Qualifier("sony")
private Speaker speaker;
private int price = 0;
public SamsungTV() {
System.out.println("SamsungTV --- 객체 생성");
}
public void setSpeaker(Speaker speaker) {
System.out.println("setSpeaker");
this.speaker = speaker;
}
public void setPrice(int price) {
System.out.println("setPrice");
this.price = price;
}
@Override
public void powerOn() {
System.out.println("SamsungTV --- 전원 켜기");
}
@Override
public void powerOff() {
System.out.println("SamsungTV --- 전원 끄기");
}
@Override
public void volumeUp() {
//System.out.println("SamsungTV --- 볼륨 켜기");
speaker.volumeUp();
System.out.println(this.price);
}
@Override
public void volumeDown() {
//System.out.println("SamsungTV --- 볼륨 줄이기");
speaker.volumeDown();
}
}
- @Resource:
객체의 데이터 타입이 아닌, 객체의 이름을 이용하여 의존성을 주입하는 어노테이션이다.
◎SamsungTV
package polymorphism;
import javax.annotation.Resource;
import org.springframework.stereotype.Component;
@Component("tv")
public class SamsungTV implements TV{
@Resource(name="sony")
private Speaker speaker;
private int price = 0;
public SamsungTV() {
System.out.println("SamsungTV --- 객체 생성");
}
public void setSpeaker(Speaker speaker) {
System.out.println("setSpeaker");
this.speaker = speaker;
}
public void setPrice(int price) {
System.out.println("setPrice");
this.price = price;
}
@Override
public void powerOn() {
System.out.println("SamsungTV --- 전원 켜기");
}
@Override
public void powerOff() {
System.out.println("SamsungTV --- 전원 끄기");
}
@Override
public void volumeUp() {
//System.out.println("SamsungTV --- 볼륨 켜기");
speaker.volumeUp();
System.out.println(this.price);
}
@Override
public void volumeDown() {
//System.out.println("SamsungTV --- 볼륨 줄이기");
speaker.volumeDown();
}
}
물론, <bean> 태그를 이용하여 등록하는 것과 어노테이션을 사용하는 것 둘 다 장,단점이 있기 때문에 이를 혼용하여 사용할 수도 있다.
1. 특정 컴포넌트에 주입되는 객체가 자주 변경되어야 할 경우에는 <bean>태그 사용
또한 ~.jar 과 같이 라이브러리 형태로 제공되는 클래스는 반드시 <bean> 태그를 사용한다.
2. 특정 컴포넌트에 주입되는 객체가 고정일 경우에는 어노테이션을 이용
'[JAVA] > Spring' 카테고리의 다른 글
[Spring] Spring JDBC 1 : 사용을 위한 기본 설정 (0) | 2021.06.17 |
---|---|
[Spring] Spring Project 제어 구조 (0) | 2021.06.16 |
[Spring] bean 6: Collection 맵핑 (0) | 2021.06.16 |
[Spring] bean 5: Namespace를 이용한 DI (0) | 2021.06.15 |
[Spring] bean 4: property를 이용한 setter DI (0) | 2021.06.15 |
- await
- javascript
- 인천 구월동 맛집
- 맛집
- react-native
- AsyncStorage
- redux
- Promise
- 파니노구스토
- 이탈리안 레스토랑
- redux-thunk
- 정보보안기사 #실기 #정리
- react
- 인천 구월동 이탈리안 맛집
- Async
- Total
- Today
- Yesterday