IT 강의 정리/윤재성의 스프링 입문

[섹션3][DI] 11~12강 생성자를 통한 주입/ Setter메서드를 통한 주입

Nellie Kim 2022. 10. 10. 12:57
728x90

11. 생성자를 통한 주입

의존성 주입(Dependency Injection)

- Bean객체를 생성할 때 Bean객체가 관리할 값이나 객체를 주입하는 것

- Bean객체 생성후 Bean객체가 가질 기본값을 자바코드로 설정하는 것이 아닌 Bean을 정의하는 xml코드에서 정의하는것

먼저 매개변수가 1개인 자바코드와 생성자주입을 비교해보자.

일반 자바코드에서는 TestBean.java에 int data1를 매개변수로 갖는 생성자를 1개 생성한 후, MainClass.java에서 TestBean t2 = new TestBean(100); 으로 생성자를 호출했다.

 

생성자를 통한 주입은 TestBean.java에 int data1를 매개변수로 갖는 생성자를 1개 생성한 후(동일),

beans.xml에 bean정의한 후 constructor-arg 에 value값을 100으로 지정(생성자주입)해서 

MainClass.java에서 TestBean obj2 = ctx.getBean("obj2", TestBean.class)으로 생성자를 호출했다.

 

이때 주의할 점은 beans.xml에서 value값을 지정할 때 type값을 지정해줘야 한다.

TestBean.java에서 생성자가 int와 double과 String을 매개변수로 갖는 생성자가 각각 있을 경우, beans.xml에서 int보다 double을, double보다 String을 우선으로 인식하기 때문에 int로 넣으려고 했던 값이 double이나 String으로 들어가는 불상사가 생길 수 있기 때문이다!

스프링에서는 String > double > int 순으로 인식한다!!!

 

TestBean.java
beans.xml
MainClass.java

 

이번에는 매개변수가 여러개 있는 생성자를 만들어서 자바코드와 생성자주입을 비교해보자.

자바코드에서는 TestBean.java에서 매개변수3개인 생성자를 만들고 MainClass.java에서 new로 매개변수3개 넣어주고 출력한다.

생성자주입에서는 beans.xml에 constructor-arg value= 를 3줄 써준다(생성자주입).  타입도 맞게 써준다.

MainClass.java에서 getBean으로 불러온다.

 

MainClass에서 불러올때 자바코드에서는 매개변수를 순서에 따라 맞게 써줘야 한다. 순서가 다르면 컴파일에러가 난다.  그런데 생성자 주입시에는 순서가 달라도 에러가 나지않고 정상적으로 주입이 된다. 그래도 나중에 헷갈릴 수 있으니 웬만하면 순서에 맞춰서 xml에 적어주자.

매개변수에 동일한 타입을 여러개 가지고있는 생성자가 있을경우 , index='0' 이런식으로 인덱스를 지정해서 순서를 정해줘도 된다.

TestBean.java
beans.xml
MainClass.java

 

지금까지 정수,실수,문자열을 주입을 해봤다. 이번에는 객체를 주입해보자.

자바코드는 아래와 같이 만드는데

객체생성자주입은 Testbean2 bean안에 DataBean의 bean을 넣어준다. DataBean객체를 보고 Testbean2에 주입해준다. 

DataBean.java
TestBean2.java
beans.xml
MainClass.java

 

이번에는 이미 만들어진 bean 객체를 주입해보자.

DataBean의 bean을 prototype으로 정의먼저 해주고, 

그 아래에 TestBean2아래에 id가 data_bean인 DataBean인 객체를 2개 매개변수로 넣어준다.

이미 만들어진 객체를 주입할땐 id 대신에 ref라는 값으로 정의해준다.

 

 

 

beans.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 id='obj1' class='kr.co.softcampus.beans.TestBean' lazy-init='true' />
	
	<bean id='obj2' class='kr.co.softcampus.beans.TestBean' lazy-init='true' >
		<constructor-arg value='100' type='int'></constructor-arg> <!-- 100이란 값을 생성자의 매개변수로 넣겠다. 이걸 주입이라고 한다! -->
	</bean> 		
	
	<bean id='obj3' class='kr.co.softcampus.beans.TestBean' lazy-init='true'>
		<constructor-arg value='11.11' type='double'></constructor-arg>
	</bean>
	
	<bean id='obj4' class='kr.co.softcampus.beans.TestBean' lazy-init='true'>
		<constructor-arg value="문자열" ></constructor-arg>
	</bean>
	
	<bean id='obj5' class='kr.co.softcampus.beans.TestBean' lazy-init='true'>
		<constructor-arg value='200' type='int'></constructor-arg>
		<constructor-arg value='22.22' type='double'></constructor-arg>
		<constructor-arg value='안녕' type='java.lang.String'></constructor-arg> <!-- String타입은 생략해도되지만, 쓰고싶으면 이렇게 쓰기! -->
	</bean>
	
	<bean id='obj6' class='kr.co.softcampus.beans.TestBean' lazy-init='true'>  <!-- 자바코드와달리 beans.xml에서는 매개변수 순서 바꿔도 알아서 순서맞춰 주입된다 -->
		<constructor-arg value='반갑습니다' type='java.lang.String'></constructor-arg>  <!-- 그래도 헷갈리니까 기왕이면 순서 맞춰서 적어주자. -->
		<constructor-arg value='200' type='int'></constructor-arg>
		<constructor-arg value='22.22' type='double'></constructor-arg>
	</bean>
	
	<!-- 이번에는 객체를 생성해서 주입해보자 -->
	<bean id='obj8' class='kr.co.softcampus.beans.TestBean2' lazy-init='true'> 
		<constructor-arg>
			<bean class='kr.co.softcampus.beans.DataBean'/>
		</constructor-arg>
		<constructor-arg>
			<bean class='kr.co.softcampus.beans.DataBean'/>
		</constructor-arg>
	</bean>
	
	<!-- 이번에는 이미 만들어진 객체를 생성해서 주입해보자 -->
	<bean id='data_bean' class='kr.co.softcampus.beans.DataBean' scope='prototype'/>
	
	<bean id='obj9' class='kr.co.softcampus.beans.TestBean2' lazy-init='true'>
		<constructor-arg ref='data_bean'/>
		<constructor-arg ref='data_bean'/>
	</bean>
	
	
</beans>

 

MainClass.java파일

package kr.co.softcampus.main;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import kr.co.softcampus.beans.DataBean;
import kr.co.softcampus.beans.TestBean;
import kr.co.softcampus.beans.TestBean2;
public class MainClass {
	public static void main(String[] args) {
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("kr/co/softcampus/config/beans.xml");
		
		TestBean t1 = new TestBean();
		t1.printData();
		
		System.out.println("----------------------------------------------");

		TestBean t2 = new TestBean(100);
		t2.printData();
		
		System.out.println("----------------------------------------------");
		
		TestBean t3 = new TestBean(11.11);
		t3.printData();
		
		System.out.println("----------------------------------------------");
		
		TestBean t4 = new TestBean("문자열");
		t4.printData();
		
		System.out.println("----------------------------------------------");
		
		TestBean t5 = new TestBean(200, 22.22, "안녕하세요");
		t5.printData();
		
		System.out.println("----------------------------------------------");
		
//		TestBean t6 = new TestBean("반갑습니다",200, 22.22); //자바코드로 생성자 호출시 이렇게 매개변수 순서안지키면 에러난다.
//		t6.printData();
		
		System.out.println("----------------------------------------------");
		
		TestBean obj1 = ctx.getBean("obj1", TestBean.class);
		obj1.printData();
		
		System.out.println("----------------------------------------------");

		TestBean obj2 = ctx.getBean("obj2", TestBean.class);
		obj2.printData();
		
		System.out.println("----------------------------------------------");
		
		TestBean obj3 = ctx.getBean("obj3", TestBean.class);
		obj3.printData();
		
		System.out.println("----------------------------------------------");
		
		TestBean obj4 = ctx.getBean("obj4", TestBean.class);
		obj4.printData();
		
		System.out.println("----------------------------------------------");
		
		TestBean obj5 = ctx.getBean("obj5", TestBean.class);
		obj5.printData();
		
		System.out.println("----------------------------------------------");
		
		TestBean obj6 = ctx.getBean("obj6", TestBean.class); 
		obj6.printData();//자바코드와달리 beans.xml에서는 매개변수 순서 바꿔도 알아서 순서맞춰 주입된다.
		
		System.out.println("----------------------------------------------");
	
		DataBean d1 = new DataBean();
		DataBean d2 = new DataBean();
		TestBean2 t200 = new TestBean2(d1, d2);
		t200.printData();
		
		System.out.println("----------------------------------------------");
		
		TestBean2 obj8 = ctx.getBean("obj8", TestBean2.class);
		obj8.printData();
		
		System.out.println("----------------------------------------------");
		
		TestBean2 obj9 = ctx.getBean("obj9", TestBean2.class);
		obj9.printData();
		
		ctx.close();
	}
}

정리) 생성자주입이란, bean객체가 생성이 될 때 각각의 변수에 어떠한 값을 집어 넣겠다고 bean.xml에 지정해주는 것을 생성자 주입이라고 한다!!!

사용법은 <constructor-arg> 뒤에 

정수,실수,문자열주입 : value / 객체주입 : class / 만들어놓은객체주입 : ref 사용!!!

 

 

12. Setter 메서드를 통한 주입

자바코드와 DI비교해보자.

자바코드에서는 TestBean클래스에서 data1을 필드로 주고, 게터세터메서드 생성한후 main클래스에서 obj1.setData1(100);로 세팅한다.

DI에서는 beans.xml에서 <property>에 name값을 주면 set + name값 (세터메소드)를 찾아서 value값을 세팅한다. 타입이 여러개일때는 타입도 지정해주기.

TestBean.java
beans.xml
MainClass.java

 

 

여러개의 필드를 주입해보자.

DataBean.java
TestBean.java

data5는 객체를 생성해서 주입, data6은 만들어놓은 DataBean객체를 주입!!

beans.xml
MainClass.java

beans.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 id='t1' class='kr.co.softcampus.beans.TestBean'>
		<property name='data1' value='100'/>
		<property name='data2' value='11.11'/>
		<property name='data3' value='true'/>
		<property name='data4' value='안녕하세요'/>
		<property name='data5'>
			<bean class='kr.co.softcampus.beans.DataBean'/>
		</property>
		<property name='data6' ref='data_bean'/>
	</bean>
	
	<bean id='data_bean' class='kr.co.softcampus.beans.DataBean'/>
	
</beans>

 

MainClass.java파일

public class MainClass {
	public static void main(String[] args) {
			
		TestBean obj1 = new TestBean();
		obj1.setData1(100);
		
		System.out.printf("obj1.data1 : %d\n", obj1.getData1());
		
		System.out.println("----------------------------------------");
		
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("kr/co/softcampus/config/beans.xml");
		
		TestBean t1 = ctx.getBean("t1",TestBean.class);
		System.out.printf("t1.data1 : %d\n", t1.getData1());
		System.out.printf("t1.data2 : %f\n", t1.getData2());
		System.out.printf("t1.data3 : %s\n", t1.isData3());
		System.out.printf("t1.data4 : %s\n", t1.getData4());
		System.out.printf("t1.data5 : %s\n", t1.getData5());
		System.out.printf("t1.data6 : %s\n", t1.getData6());
		
		ctx.close();
	}
}

정리)  Bean객체를 생성할때 객체의 기본값을 Setter메서드를 통해 주입할 수 있다. 

<property name = ' ' > 뒤에 

정수,실수,문자열주입 : value / 객체주입 : class / 만들어놓은객체주입 : ref 사용!!!

 

출처 :  [인프런]윤재성의 스프링 프레임워크 개발자를 위한 실습을 통한 입문 과정