Spring

Setter Injection

wintertreey 2024. 7. 4. 14:31

앞서 constructor injection에 대해서 실습해보았다. 

이번엔 setter injection. 

 

생성자의 경우 객체생성을 1번만 할 수있다.

그에 반해 setter의 경우 생성자보다 더 유연하다는 장점이 있다. 

 

 


연습

pom.xml

maven 프로젝트이기에 dependency 부분 추가해서 넣어준다.

 

ShowData.java

package pack;

public class ShowData {
	public String processNickName() {
		return "홍길동";
	}
	
	public String processHobby() {
		return "프로그래밍 만들기";
	}
}

 

MyProcess.java

package pack;

public class MyProcess { //DI 중 setter injection사용
	//extends상속 지양. 
	private int nai; //기본형
	private String name;
	private ShowData showData; //참조형. ShowData타입의 showData객체 생성. 클래스의 포함관계.
	
	public MyProcess() {
		// TODO Auto-generated constructor stub
	}
	
	public void setNn(int nai) {
		this.nai = nai;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setShowData(ShowData showData) {
		this.showData = showData;
	}
	
	public void displayData() {
		System.out.println("이름은 "+name+"나이는 "+nai+
				"별명은 "+showData.processNickName()+"취미는 "+showData.processHobby());
	}
}

 

SetterMain.java

package pack;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SetterMain {
	
	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("configuration.xml");
		
		MyProcess my= (MyProcess)context.getBean("myProcess");//bean id명
		my.displayData();
	}
}

 

 

configuration.xml

이 부분이 DI작업해주는 부분. 

setter를 사용하는 방법이 여러가지가 있다. 

 

일반적인 setter 사용

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	<!-- 둘이 이름이 같을때 다르게 하기위해 접두사 xsi -->
	<!-- 이 자유로움에 <bean>으로 제한을 걸어줌 -->
	
	<!-- 1. 일반적인 setter 사용 -->
	<bean id="myProcess" class="pack.MyProcess"><!-- 생성자를 부르는것.MyProcess클래스의 myProcess기본생성자 호출. -->
	<property name="nn" value="25" /><!-- setNn를 불러 값25를 넣어준다. -->
	<property name="name" value="김치국" />
	<property name="showData" ref="show" /><!-- 객체라 value로 줄수가 없다. 별도의 객체를 하단에 적어주고 ref로 그주소가져오기 -->
	</bean>
	<bean id="show" class="pack.ShowData" />

 

기본 생성자를 만들어주고, property를 이용해 값을 넣어준다. 

앞서 기입한 MyProcess.java를 보면 일부러 setNai가 아닌 setNn이라 적어주었다. nn이라 적었지만, 이를 SetNn이라고 생각하면 된다.

 

showData.java의 경우는 객체이기에 value로 값을 기입할 수  가 없다. 이때 사용하는게 ref. 

상단 하단 무관하게 해당 클라스 객체를 생성해주고 해당 id 명을 ref에 적어주자. 

 

같은 내용, 다른 표현법 2가지를 더 연습해보자.

 

<bean id="myProcess" class="pack.MyProcess">
		<property name="nn">
			<value>26</value>
		</property>
		<property name="name">
			<value>김만두</value>
		</property>
		<property name="showData">
			<bean class="pack.ShowData" />
		</property>
	</bean>

 

이는 value값을 따로 태그로 분류해서 넣어주 모습이다.

 

또 다른 방법은 xml namespace를 이용하는 법이다.

<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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="myProcess" class="pack.MyProcess"
		p:nn="27"
		p:name="김찐빵"
		p:showData-ref="show"/>
	
	<bean id="show" class="pack.ShowData" />
</beans>

 

상단의 부분을 자세히 살펴보면 :p라는 코드가 한 줄 추가되었음을 알수 있다. 

key: value 형식으로 값과 ref 를 적어줄 수 도 있다.

 


 

같은 방법으로 구구단을 연습한 코드를 첨부해 기록해둔다. 

 

GuguDan.java

package pack;

public class GuguDan {
	public int[] numberCalc(int dan) {
		int[] re = new int[9];
		
		for(int i =0; i<re.length; i++) {
			re[i] = dan*(i+1);
		}
		return re;
	}
}

 

OurProcess.java

package pack;

import java.util.Iterator;

public class OurProcess {
	private String name;
	private int su;
	private GuguDan guguDan;
	
	public void setName(String name) {
		this.name = name;
	}
	public void setSu(int su) {
		this.su = su;
	}
	public void setGuguDan(GuguDan guguDan) {
		this.guguDan = guguDan;
	}
	
	@Override
	public String toString() {
		// 모든 클래스의 수퍼클래스인 object이 갖고있는 tostring을 오버라이딩한다
		int[] results= guguDan.numberCalc(su);
		String str = "";
		for(int i=0; i<results.length; i++) {
			str += su+ "*" + (i+1) + "=" + results[i] +"\n";
		}
		return "작성자: "+ name+ "\n" + su + "단 결과: " +"\n" + str;
	}
}

 

configuration.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	
	<bean name="gugu" class="pack.GuguDan"></bean>
	
	<bean name="our" class="pack.OurProcess">
		<property name="name" value="우주인"/>
		<property name="su" value="7"/>
		<property name="guguDan" ref="gugu"/>
	</bean>
</beans>

 

SetterMain.java

package pack;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SetterMain {
	
	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("configuration.xml");
		
		OurProcess ourP= (OurProcess)context.getBean("our");//bean id명
		System.out.println(ourP);
		//System.out.println(ourP.toString()); //상동
	}
}

 

콘솔 출력물