의존성 관리-1

2022. 7. 14. 17:09Spring

728x90

 

이번 포스팅에서는 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 인젝션과 같은 원리지만, 더 간단하게 사용할 수 있다.

 

 

이상입니다.

728x90

'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