@markdown
# Spring 핵심 개념(IoC, DI)
<br/>
## Spring IoC(Inversion of Control) 제어역행
____
- 개발자가 직접 객체간 의존관계를 연결하던 제어권을, 서블릿, EJB를 관리하는 `container`에게 넘긴 것
- 객체의 생성부터 생명주기의 관리까지 모든 객체에 대한 제어권이 바뀐 것(개발자->컨테이너)을 의미한다.
- 다른 곳에서 생성된 클래스를 가져와서 사용하는 방법(결합도를 낮춤)
- 컨테이너에서 관리되고 있는 객체를 개발자가 필요할 때 코드 주입(의존 주입)을 통해 사용하는 것
## Spring Container
____
- `Spring Framework`에서 `Container` 기능을 제공해주는 클래스를 의미
- `Container` : Bean 클래스를 관리하는 주체
- `Bean` : `Spring`에서 관리되는 객체를 나타냄
- 객체를 재사용하는 방식으로, 기본적으로 `Singleton` 패턴으로 객체가 생성된다.
- `Spring xml` 파일 : 어떤 클래스의 `Setter`로 주입할지, `Constructor`로 주입할지 등의 설정 정보가 들어있는 파일
- 종류로 `Bean Factory`, `Application Context`가 있는데 `Application Context`를 가장 많이 사용함
### Bean
- `Spring Framework`에 의해 `LifeCycle`이 관리되는 클래스
- `XML`에 <bean /> 태그를 이용하여 등록
- `id` : 여러 개의 Bean 클래스를 식별하기 위한 이름 설정
- `class` : 사용하려는 Bean 클래스의 패키지명을 포함한 클래스명
### BeanFactory
- `Bean`의 LifeCycle(생성과 소멸)을 관리
- `Spring XML` 파일로 설정 정보를 저장하여, `Spring`이 여러가지 `Container Service`를 사용하는데 참조한다.
- `Resource` 클래스
- `ClassPathResource` : Xml 설정파일을 로딩하는 단순한 BeanFactory
- `FileSystemResource` : 지정된 파일 시스템으로부터 Xml 설정파일 로딩
- `BeanFactory Container` : `src/main/resources` 경로에 `beanFactory.xml` 파일 생성
### beanFactory.xml 코드
<pre><code class="xml" style="font-size:14px"><?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">
<!-- class 파일 등록 : 패키지이름.클래스파일 등록 -->
<bean id="hello" class="basic.Hello"/>
</beans>
</code></pre>
- `src/main/java` 경로에 `hello.java`, `helloMain01.java` 파일 생성
### hello.java 코드
<pre><code class="java" style="font-size:14px">public class Hello {
private String msg;
public Hello() {
System.out.println("Bean 생성");
msg = "hello";
}
public void printMsg(){
System.out.println("msg : " + msg);
}
}
</code></pre>
<br/>
### helloMain01.java 코드
<pre><code class="java" style="font-size:14px">import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
//개발자가 자기 코드에 객체를 생성하고 관리하는 방식
public class helloMain01 {
public static void main(String[] args) {
//class path는 src/main/resources 경로
Resource resource = new ClassPathResource("beanContainer.xml");
BeanFactory factory = new XmlBeanFactory(resource);
Hello obj1 = (Hello) factory.getBean("hello");
Hello obj2 = (Hello) factory.getBean("hello");
obj1.printMsg();
System.out.println("obj1 : " + obj1);
System.out.println("obj2 : " + obj2);
//obj1과 obj2가 객체주소가 같다.
}
}
실행결과
msg : hello
obj1 : basic.Hello@29444d75
obj2 : basic.Hello@29444d75
</code></pre>
## BeanFactory vs ApplicationContext
____
- `BeanFactory`는 객체 생성 시점이 `getBean()`을 호출할 때이다.
- `ApplicationContext`는 클래스가 `new`되는 시점에 객체가 생성된다.
### 실행결과로 보는 Container 객체 생성 시점
<pre><code class="java" style="font-size:14px"><beanFactory.xml>
<bean id="hello1" class="basic.Hello"/>
<bean id="hello2" class="basic.Hello"/>
</code></pre>
<pre><code class="java" style="font-size:14px"><BeanFactory java 코드>
Resource resource = new ClassPathResource("beanContainer.xml");
BeanFactory factory = new XmlBeanFactory(resource);
Hello obj1 = (Hello) factory.getBean("hello1");
obj1.printMsg();
Hello obj2 = (Hello) factory.getBean("hello2");
obj2.printMsg();
실행결과
Bean 생성
msg : hello
Bean 생성
msg : hello
</code></pre>
<pre><code class="java" style="font-size:14px"><ApplicationContext java 코드>
ApplicationContext context = new FileSystemXmlApplicationContext("beanContainer.xml");
Hello obj1 = (Hello) context.getBean("hello1");
obj1.printMsg();
Hello obj2 = (Hello) context.getBean("hello2");
obj2.printMsg();
실행결과
Bean 생성
Bean 생성
msg : hello
msg : hello
</code></pre>
## Spring DI(의존 주입)
____
- `DI(Dependency Injection)` : 각 `class` 사이의 의존관계를 `Bean` 설정 정보를 바탕으로 `container`가 자동으로 연결해 주는 것을 말한다.
- `Spring`에서 `IoC`를 제공하는 형태 중 하나(DL, DI)
- 의존관계가 발생함으로서 결합도를 낮춰, 코드 수정을 피할 수 있다.
### DI 종류
- `Setter Injection` : 클래스 setter 메소드를 이용해 객체 의존관계 연결
- `Constructor Injection` : 클래스 생성자를 사용해 객체 의존관계 연결
- `Method Injection` : `Singleton` 패턴으로 생성된 인스턴스 객체와 싱글톤이 아닌 인스턴스 간 의존관계를 연결시킬 때
- 코드 작성 방법
- `Spring`에서 제공하는 DI 활용
- 개발자가 코드에서 객체를 생성하지 않는 방식
- `XML` 환경설정 파일 또는 `Annotation`을 사용해 객체 주입
### Setter Injection
<pre><code class="java" style="font-size:14px">A a = new A();
B b = new B();
b.setClass(a); //DI 시점
</code></pre>
<br/>
### Constructor Injection
<pre><code class="java" style="font-size:14px">A a = new A();
B b = new B(a); //DI 시점
</code></pre>
<br/>
### XML에서의 DI Constructor 주입 방법
- `<constructor-arg>` 태그 사용
- 클래스 생성자의 파라미터 순서대로 주입 시켜준다.
- `index` 속성으로 순서를 설정할 수도 있다.(0부터 시작)
- 아래에서 나올 `Car`와 `Tire` 클래스는 의존관계로, 자동차에 바퀴를 추가하는 개념으로 사용한 것
<pre><code class="java" style="font-size:14px"><bean id="Tire" class="package.TireClass">
<bean id="car" class="package.CarClass"/>
<!-- Car Class의 생성자 매개변수 넘기기, 숫자와 클래스 -->
<constructor-arg index="0"><value>2</value></constructor-arg>
<constructor-arg index="1" value="1"></constructor-arg>
<constructor-arg ref="tire"></constructor-arg>
</bean>
</code></pre>
<br/>
### XML에서의 DI Setter 주입
- `<property>` 태그 사용
- 클래스 `setter()` 메소드를 사용해 주입 시켜준다.
- `ApplicationContext`에서는 로딩 될 때 객체가 만들어졌기 때문에 `property` 속성을 사용할 수 있다.
<pre><code class="java" style="font-size:14px"><bean id="Tire" class="package.TireClass">
<bean id="car" class="package.CarClass"/>
<property ref="tire"/>
</bean>
</code></pre>
'웹 프로그래밍' 카테고리의 다른 글
Spring - AOP annotaion 용어, 패턴매칭, 자동주입 (0) | 2017.07.07 |
---|---|
Spring - DI 자동 주입, AOP (0) | 2017.07.06 |
Spring - Maven 설치 및 Eclipse 환경설정 하기 (0) | 2017.07.04 |
Ajax 사용한 Daum 검색 API 사용하기 (0) | 2017.06.21 |
AJAX 비동기 처리 방식 (0) | 2017.06.20 |