[의존성 주입] : DI (Dependency Injection)
-Bean 객체 생성 시, 해당 Bean 객체가 관리할 값이나 객체를 주입해주는 것 의미 -Bean 객체 생성 후, Bean 객체가 가질 기본 값을 xml코드에서 주입해주는 개념 -객체 간의 의존을 주입한다는 것. |
11강. [생성자를 통한 주입]
[생성자를 통한 주입]
-Bean 정의할 때, <contructor-arg> 태그 이용해서 값을 주입
value : 기본 자료형 값과 문자열 값 설정 ref : 객체를 설정 type : 저장할 값의 타입 설정 index : 지정된 값을 주입할 생성자의 매개변수 인덱스 번호 |
[객체 주입]
1) 직접 객체 생성하여 객체 주입하기
2) 이미 존재하는 객체를 ref 속성으로 지정하여 주입하기
kr.co.softcampus.config.[beans.xml] 빈 등록
<!-- Bean 등록 -->
<bean id='obj1' class='kr.co.softcampus.beans.TestBean1' lazy-init='true' />
<bean id='obj2' class='kr.co.softcampus.beans.TestBean1' lazy-init='true'>
<constructor-arg value='100' type='int' /> //주입 값
</bean>
//기본적으로 스프링은 String > double > int 순으로 우선 처리함
<bean id='obj3' class='kr.co.softcampus.beans.TestBean1' lazy-init='true'>
<constructor-arg value='11.11' type='double' />
</bean>
<bean id='obj4' class='kr.co.softcampus.beans.TestBean1' lazy-init='true'>
<constructor-arg value='문자열' />
</bean>
//기본적으로 스프링은 생성자 여러 개일 때 값을 순서대로 줘야 함
<bean id='obj5' class='kr.co.softcampus.beans.TestBean1' lazy-init='true'>
<constructor-arg value='200' type='int' />
<constructor-arg value='22.22' type='double' />
<constructor-arg value='안녕하세요' type='java.lang.String' />
</bean>
//단, index 속성으로 순서 지정해줄 수도 있음
<bean id='obj7' class='kr.co.softcampus.beans.TestBean1' lazy-init='true'>
<constructor-arg value='33.33' type='double' index='1' />
<constructor-arg value='33' type='int' index='2' />
<constructor-arg value='안녕하세요' type='java.lang.String' index='3' />
</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>
//의존 주입 대상 객체가 이미 존재하는 개체인 경우, ref 속성으로 주입 객제 직접 지정
<bean id='data_bean' class='kr.co.softcampus.beans.TestBean2' lazy-init='true'>
<constructor-arg ref='data_bean' />
<constructor-arg ref='data_bean' />
</bean>
</beans>
12강. [Setter 메소드를 통한 주입]
[Setter 메소드 통한 주입]
-Bean 객체가 가질 기본 값을 Setter() 메소드 통해 주입 가능
-Bean 정의할 때, <property> 태그 사용하여 의존 주입 값 넣음
name : 데이터를 주입할 프로퍼티 이름 value : 기본 자료형 및 문자열 주입할 때 사용하는 속성 ref : 객체 주소값 주입할 때 사용하는 속성 |
[객체 주입]
1) 직접 객체 생성하여 주입하기
<bean id = 't1' class = 'kr.co.softcampus.beans.TestBean'>
<property name = "data5"> //내부에 주입 대상 객체 정의하고 주입
<bean class='kr.co.softcampus.beans.DataBean' />
</property>
</bean>
2) 이미 정의되어 있는 객체를 ref 속성으로 지정하여 주입하기
<bean id = 't1' class = 'kr.co.softcampus.beans.TestBean'>
//이미 정의되어 있는 객체를 ref속성으로 지정하여 주입
<property name = "data6" ref = "data_bean" />
</bean>
<bean id = 'data_bean' class='kr.co.softcampus.beans.DataBean'/> //이미 정의된 객체
13강. [컬렉션 주입]
[컬렉션 주입]
-Bean에 주입하는 멤버가 ‘컬렉션’인 경우, 컬렉션이 관리할 객체를 초기에 설정할 수 있다.
ex. List/ Map/ Set/ Property
-Bean에 주입할 멤버 타입이 컬렉션인 경우, 다시 컬렉션이 관리할 객체를 초기에 설정할 수 있다.
[List]
1) 객체 단위 리스트에 객체 주입 시, 직접 생성 후 주입 가능
2) 객체 단위 리스트에 객체 주입 시, 이미 정의된 빈을 ref 속성으로 지정하여 주입 가능
[Set]
-중복된 값은 담지 못함(정수값, 실수값 동일값인 경우 또 못 담음)
-중복된 객체는 담지 못함(동일한 종류, 즉 주소값 같은 객체는 다시 못담음)
kr.co.softcampus.beans.[TestBean.java] //빈 등록될 객체
public class TestBean {
//필드
// 컬렉션 : <List>
private List<String> list1; //컬렉션 리스트
private List<Integer> list2;
private List<DataBean> list3; //객체 담는 리스트
// 컬렉션 : <Set>
private Set<String> set1;
private Set<Integer> set2;
private Set<DataBean> set3;
// 컬렉션 : <Map>
private Map<String, Object> map1;
// 컬렉션 : <Properties>
private Properties prop1;
...get/set() 메소드
}
kr.co.softcampus.config.[beans.xml] //xml파일에 빈 등록
<!-- Bean 등록 -->
<bean id='t1' class='kr.co.softcampus.beans.TestBean'>
<!--제네릭이 String인 List -->
<property name="list1">
<list>
<value>문자열1</value>
<value>문자열2</value>
<value>문자열3</value>
</list>
</property>
<!-- 제네릭이 Integer인 List -->
<property name="list2">
<list>
<value type='int'>100</value>
<value type='int'>200</value>
<value type='int'>300</value>
</list>
</property>
<!-- 제네릭이 DataBean인 list -->
<property name="list3">
<list>
<bean class='kr.co.softcampus.beans.DataBean'/>
<bean class='kr.co.softcampus.beans.DataBean'/>
<ref bean = 'data_bean'/>
<ref bean = 'data_bean'/>
</list>
</property>
<!-- 제네릭이 String인 Set -->
<property name = "set1">
<set>
<value>문자열1</value>
<value>문자열2</value>
<value>문자열3</value>
</set>
</property>
<!--제네릭이 Integer인 Set -->
<property name = "set2">
<set>
<value type = 'int'>100</value>
<value type = 'int'>200</value>
<value type = 'int'>300</value>
</set>
</property>
<!-- 제네릭이 DataBean인 Set -->
<property name = "set3">
<set>
<bean class='kr.co.softcampus.beans.DataBean'/>
<bean class='kr.co.softcampus.beans.DataBean'/>
<ref bean='data_bean'/>
<ref bean='data_bean'/>
</set>
</property>
<!-- 제네릭이 String, Object인 Map -->
<property name='map1'>
<map>
<entry key='a1' value='문자열'/>
<entry key='a2' value='100' value-type='int'/>
<entry key = 'a3'>
<bean class='kr.co.softcampus.beans.DataBean'/>
</entry>
<entry key='a4' value-ref='data_bean'/>
<entry key='a5'>
<list>
<value>문자열1</value>
<value>문자열2</value>
<value>문자열3</value>
</list>
</entry>
</map>
</property>
<property name='prop1'>
<props>
<prop key='p1'>문자열1</prop>
<prop key='p2'>문자열2</prop>
<prop key='p3'>문자열3</prop>
</props>
</property>
</bean>
<bean id = 'data_bean' class='kr.co.softcampus.beans.DataBean' scope = 'prototype'/>
</beans>
kr.co.softcampus.main.[MainClass.java]
public class MainClass {
public static void main(String[] args) {
// TODO Auto-generated method stub
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("kr/co/softcampus/config/beans.xml");
TestBean t1 = ctx.getBean("t1", TestBean.class);
List<String> list1 = t1.getList1();
for(String str: list1) {
System.out.printf("list1 : %s\n", str);
}
List<Integer>list2 = t1.getList2();
for(int value : list2) {
System.out.printf("list2 : %d\n", value);
}
List<DataBean>list3 = t1.getList3();
for(DataBean obj : list3) {
System.out.printf("list3 : %s\n", obj);
}
System.out.println("----------------");
//Set의 경우 중복된 값을 주입할 경우 하나만 인식하고 더 이상 담지 X
Set<String> set1 = t1.getSet1();
Set<Integer> set2 = t1.getSet2();
Set<DataBean> set3 = t1.getSet3();
for(String str: set1) {
System.out.printf("set1: %s\n", str);
}
for(int value: set2) {
System.out.printf("Set2: %s\n", value);
}
for(DataBean obj : set3) {
System.out.printf("Set3:%s\n", obj);
}
System.out.println("----------------");
Map<String, Object> map1 = t1.getMap1();
String a1 = (String)map1.get("a2");
int a2 = (Integer)map1.get("a3");
DataBean a3 = (DataBean)map1.get("a4");
DataBean a4 = (DataBean)map1.get("a5");
List<String> a5 = (List<String>)map1.get("a5");
System.out.printf("a1:%s\n", a1);
System.out.printf("a2:%d\n", a2);
System.out.printf("a3:%s\n", a3);
System.out.printf("a4:%s\n", a4);
for(String str: a5) {
System.out.printf("a5", str);
}
System.out.println("----------------");
//프로퍼티 타입 = 문자열 값만 사용
Properties prop1 = t1.getProp1();
String p1 = prop1.getProperty("p1");
String p2 = prop1.getProperty("p2");
String p3 = prop1.getProperty("p3");
System.out.printf("p1 : %s\n", p1 );
System.out.printf("p2 : %s\n", p2 );
System.out.printf("p3 : %s\n", p3 );
ctx.close();
}
14강. [자동 주입]
[자동 주입]
-Bean 정의 시, 객체 직접 주입은 기본적으로 생성자/setter()를 통해 했다. -그런데, Spring은 객체 자동 주입 기능을 제공한다. -자동 주입은 이름/타입/생성자를 통해 가능하며 <auto wire> 로 적용된다. * 자동 주입 대상은 오직 객체만 가능. String or int 타입은 직접 주입함 |
▶[이름을 통한 주입]
-byName : 빈 객체의 프로퍼티 이름과 정의된 빈 이름이 같은 것을 찾아서 자동으로 주입됨
<bean id='obj2' class='kr.co.softcampus.beans.TestBean1' autowire='byName'/> <bean id='data1' class='kr.co.softcampus.beans.DataBean1'/> <bean id='data2' class='kr.co.softcampus.beans.DataBean1'/> |
- 빈으로 등록한 TestBean1 의 경우, 내부에 data1/data2 로 이름지어진 DataBean1 타입의 객체 필드를 가지고 있다. 빈 등록 시, autowire 속성 값에 ‘byName’을 주었으므로 이 빈은 내부의 객체 주입 시, 이름을 우선하여 자동 주입을 할 것이다.
▶[타입을 통한 주입]
-byType : 빈 객체의 프로퍼티 타입과 정의된 빈의 타입이 일치할 경우 자동 주입된다.
-이 때, 동일 타입 빈이 2개 이상 정의되어 있을 경우 오류 발생함
<bean id='obj3' class='kr.co.softcampus.beans.TestBean2' autowire='byType'/> <bean id ='data_bean2' class='kr.co.softcampus.beans.DataBean2'/> |
- 빈으로 등록한 TestBean2 의 경우, 내부에 DataBean2 타입의 객체 필드를 가지고 있다.
빈 등록 시, autowire 속성 값에 ‘byTytpe’을 주었으므로 이 빈은 내부의 객체 주입 시, 타입을 우선하여 자동 주입을 할 것이다.
▶[생성자를 통한 주입]
-constructor : 생성자의 매개변수 타입과 정의된 빈의 타입이 일치할 경우 자동 주입된다.
-이 때, 동일 타입 빈이 2개 이상 정의되어 있을 경우 오류 발생함
<bean id='obj7' class='kr.co.softcampus.beans.TestBean3' autowire='constructor'> <constructor-arg value='200' index='0' type = 'int'/> <constructor-arg value='문자열2' index='1' /> </bean> |
- 빈으로 등록한 TestBean3 의 경우, 내부에 DataBean2 타입 객체를 매개변수로 갖는 생성자를 가지고 있다. 빈 등록 시, autowire 속성 값에 ‘constructor’ 값을 주었으므로 이 빈은 내부의 객체 주입 시 생성자의 매개변수 타입과 일치하는 타입의 빈을 우선하여 자동 주입할 것이다.
▶[따로 자동 주입 설정하지 않을 경우, 기본 자동 주입에 대한 설정도 가능]
default-autowire ='byName’ |
[참고] - SpringFramework 개발자를 위한 실습을 통한 입문 과정 |
'Web(웹)_관련 공부 모음 > [강의] SpringFramework' 카테고리의 다른 글
JDBC & MyBatis - [DB 연동] (0) | 2022.02.18 |
---|---|
@Component - [ @Component 설정] (0) | 2022.02.16 |
@어노테이션 - [Annotation 활용하기] (0) | 2022.02.14 |
스프링 IoC [Inversion of Control] (0) | 2022.02.11 |
Maven 기반-[기본 스프링 프로젝트 생성] (0) | 2022.02.11 |