2022. 7. 14. 17:09ㆍSpring
이번 포스팅에서는 Dependency Injection 방식을 다루겠습니다.
스프링의 의존성 관리 방법
- Dependency LookUp : 검색
- 컨테이너가 애플리케이션 운용에 필요한 객체를 생성하고 클라이언트는 생성한 객체를 검색하여 사용하는 방식
- Dependency Injection : 주입
- 객체 사이의 의존관계를 스프링 설정파일에 등록된 정보를 바탕으로 컨테이너가 자동으로 처리해 주는 방식
의존성 주입이 필요한 이유는 아래와 같다.
public class SamsungTV implements TV {
private SonySpeaker speaker;
public SamsungTV() {
System.out.println("SamsungTV 객체 생성");
}
public void volumeUp() {
speaker= new SonySpeaker();
speaker.volumeUp();
}
public void volumeDown() {
speaker = new SonySpeaker();
speaker.volumeDown();
}
...
}
public class TvUser(){
public static void main(String args[]){
TV tv = (TV) factory.getBean("tv");
tv.powerOn();
tv.volumeUp();
tv.volumeDown();
tv.powerOff();
}
}
applicationContext.xml의 <bean>
<bean id="tv" class="sonny.spring.polymorphism.SamsungTV"/>
위의 코드는 SamsungTv가 SonySpeaker라는 필드를 가지고 있는 상황이다. 그리고 TvUser class를 실행하면, xml파일에 있는 <bean>태그가 실행된다.
여기서 실행 결과는 tv.powerOn() 메소드 등이 실행 될때마다 SonySpeaker의 객체가 새로 만들어진다.
이는 크나큰 문제이며 더한 문제는 나중에 유지보수과정에서 SonySpeaker를 다른 것으로 교체해야 할 때 일일 코드를 변경해야 하는 문제가 있다.
따라서, 스프링에서 의존성을 주입하여 이러한 문제를 해결하려고 한다.
Dependency Injection : 주입
- Constructor(생성자)기반으로 하는 Constructor Injection
- Setter 메서드를 기반으로 하는 Setter Injection
- p 네임스페이스 사용하기
생성자 인젝션
<constructor - arg> 태그
스피커를 여러 종류를 사용하기 위해서 interface Speaker를 만들고 SonySpeaker class와 AppleSpeaker class에 구현함.
그리고 SamsungTV 클라스의 멤버로 Speaker 멤버변수를 생성.
public class SamsungTV implements TV {
private Speaker speaker;
private int price;
public SamsungTV(Speaker speaker, int price) {
System.out.println("SamsungTV 객체 생성 : 생성자 인젝션 - 다중 매핑");
this.speaker = speaker;
this.price = price;
}
public void powerOn() {
System.out.println("SamsungTV 전원을 켠다. (가격 : " + price + "원)");
}
public void powerOff() {
System.out.println("SamsungTV 전원을 끝다.");
}
@Override
public void volumeUp() {
speaker.volumeUp();
}
@Override
public void volumeDown() {
speaker.volumeDown();
}
}
<bean id="tv" class ="sonny.spring.polymorphism.SamsungTV" scope = "singleton">
<constructor-arg ref = "apple"></constructor-arg>
<constructor-arg value = "3000000"></constructor-arg>
</bean>
<bean id = "apple" class = "sonny.spring.polymorphism.AppleSpeaker"></bean>
<bean id = "sony" class = "sonny.spring.polymorphism.SonySpeaker"></bean>
<constructor-arg> 태그
속성 | 설명 |
index | Contructor의 몇 번재의 인수에 값을 전달할 것인가를 결정 |
ref | 자식요소 <ref bean = "빈이름/"> 대신에 사용 |
value | 자식요소 <value>값</value> 대신에 사용 |
이렇게 xml을 설정하면, 어떤 자바코드도 변경하지 않고 xml설정을 변경하는 것 만으로 스피커를 교체할 수 있다.
Setter 인젝션
<property> 태그
Setter 인젝션은 프로퍼티 설정 방식이라 한다. setxxx() 형태의 설정 메소드를 사용해서 필요한 객체와 값을 전달 받는다.
setxxx()형태의 프로피터의 이름은 xxx가 된다.
public class SamsungTV implements TV {
private Speaker speaker;
private int price;
public SamsungTV() {
System.out.println("default 생성자 생성");
}
public Speaker getSpeaker() {
return speaker;
}
public void setSpeaker(Speaker speaker) {
System.out.println("setSpeaker() 메서드 호출");
this.speaker = speaker;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
System.out.println("setPrice() 메서드 호출");
this.price = price;
}
public void powerOn() {
System.out.println("SamsungTV 전원을 켠다. (가격 : " + price + "원)");
}
public void powerOff() {
System.out.println("SamsungTV 전원을 끝다.");
}
public void volumeUp() {
speaker.volumeUp();
}
public void volumeDown() {
speaker.volumeDown();
}
}
<bean id="tv" class ="sonny.spring.polymorphism.SamsungTV" scope = "singleton">
<property name = "speaker" ref = "apple"></property>
<property name = "price" value = "3000000"></property>
</bean>
<bean id = "apple" class = "sonny.spring.polymorphism.AppleSpeaker"></bean>
Setter 메서드는 스프링 컨테이너가 자동으로 호출하는 시점은 <bean> 객체가 생성된 직후이다.
따라서, setter 인젝션이 동작하려면 default 생성자가 반드시 필요하다.
<property> 태그
속성 | 설명 |
ref | 자식요소 <ref bean = "빈이름/"> 대신에 사용 |
value | 자식요소 <value>값</value> 대신에 사용 |
p 네임스페이스
xml 네임스페이스를 이용한 설정 -> <property> 태그를 사용하지 않고 더 간단한 방법으로 프로퍼티 값을 설정할 수 있다.
<beans>태그에 아래의 코드 추가
xmlns:p="http://www.springframework.org/schema/p"
<bean id="tv" class ="sonny.spring.polymorphism.SamsungTV" scope = "singleton"
p:speaker-ref = "apple" p:price="3000000"/>
<bean id = "apple" class = "sonny.spring.polymorphism.AppleSpeaker"></bean>
p:변수명-ref = "참조할 객체 아이디"
p:변수명 = "설정한 값"
Setter 인젝션과 같은 원리지만, 더 간단하게 사용할 수 있다.
이상입니다.
'Spring' 카테고리의 다른 글
Spring - AOP (0) | 2022.07.19 |
---|---|
의존성 관리 -2 (0) | 2022.07.15 |
스프링 XML 설정 (0) | 2022.07.14 |
스프링 프레임 워크를 배우기 전 용어 정리 (0) | 2022.07.08 |
웹 서버와 Web Application Server (0) | 2022.05.14 |