[Spring] DI / IoC (Bean 객체 생성_01)

스프링의 특징 중 DI / IoC, AOP, OCP가 있었습니다.
그중 DI는 객체간의 결합을 느슨하게 하는 스프링의 핵심기술입니다.
쉽게 말하면 결합도를 낮추기 위함입니다.
결합도란?
강결합 : 객체 간 결합도가 강한 프로그램

- HelloApp 에서 MessageBean을 직접 객체 생성하여 사용하는 경우에 MessageBean 클래스를 다른 클래스로 변경할 경우, HelloApp의 소스를 수정해주어야합니다.
약결합 : 인터페이스를 사용하여 객체 간 결합도를 낮춘 프로그램

인터페이스를 활용하여 결합도를 낮춘 경우
- HelloApp 은 MessageBean 이라는 인터페이스를 톨해 객체를 사용할 경우
- 일반적으로 팩토리 메서드를 활용하여, 사용할 객체를 생성합니다. 위의 경우 MessageBean이라는 이름의 MessageBeanKo의 객체가 생성이 되던 MessageBeanEn의 객체가 생성이 되던 HelloApp은 수정될 필요가 없습니다.

스프링과 인터페이스를 활용하여 결합도를 낮춘 경우
- 프로그램에서 필요한 객체를 스프링컨테이너가 미리 생성하여 이 객체를 필요로 하는 프로그램에 생성자, setter 또는 메서드를 통해서 전달(주입)합니다.
- 어떠한 객체를 생성하여 전달할지는 디스크립터 파일(XML)을 사용합니다.
기본 세팅을 마친 후 패키지를 만들어서 MessageBean인터페이스와 MessageBeanEn, MessageBeanKo, MTest클래스를 만들어줍니다!
그리고 Beans.xml파일을 만들건데요!

Spring Bean Configuration File로 만들어주세요!

MessageBean.java
package com.test03;
public interface MessageBean {
public void sayHello(String name);
}
MessageBeanEn.java
package com.test03;
public class MessageBeanEn implements MessageBean {
@Override
public void sayHello(String name) {
System.out.println("Hello, " + name + "!!");
}
}
MessageBeanKo.java
package com.test03;
public class MessageBeanKo implements MessageBean {
@Override
public void sayHello(String name) {
System.out.println("안녕하세요, " + name + "님");
}
}
MTest.java
package com.test03;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MTest {
public static void main(String[] args) {
ApplicationContext factory = new ClassPathXmlApplicationContext("com/test03/beans.xml");
MessageBean korean = (MessageBean) factory.getBean("korean");
MessageBean english = (MessageBean) factory.getBean("english");
korean.sayHello("스프링!");
english.sayHello("Spring");
}
}
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="korean" class="com.test03.MessageBeanKo"></bean>
<bean id="english" class="com.test03.MessageBeanEn"></bean>
</beans>
실행결과

MessageBean인터페이스를 상속받은 MessageBeanKo와 MessageBeanEn를 만들고 각각의 클래스에 sayHello메서드를 만들었습니다.
Beans.xml에서
<bean id="korean" class="com.test03.MessageBeanKo"></bean>
<bean id="english" class="com.test03.MessageBeanEn"></bean>
의 코드를 작성했고 이는 각각
MessageBeanKo korean = new MessageBeanKo();
MessageBeanEn english = new MessageBeanEn();
와 동일한 코드입니다.
즉, bean은 객체라고 생각하시면 되겠습니다.
이를 main메서드에서 factory메서드를 통해 사용하게 됩니다.
ApplicationContext factory = new ClassPathXmlApplicationContext("com/test03/beans.xml");
MessageBean korean = (MessageBean) factory.getBean("korean");
MessageBean english = (MessageBean) factory.getBean("english");
korean.sayHello("스프링!");
english.sayHello("Spring");
ApplicationContext / ClassPathXmlApplication
BeanFactory <- ApplicationContext <- ClassPathXmlApplicationContext
스프링의 ApplicationContext 객체는 스프링 컨테이너의 인스턴스이다.
스프링은 ApplicationContext의 몇가지 기본 구현을 제공한다.
그 중 ClassPathXmlApplicationContext는 XML 형식의 독립형 어플리케이션에 적합하다.
(지정된 classpath에서 xml 파일을 읽어서 스프링 컨테이너 객체 생성)
content : 기능
context : 기능을 구현하기 위한 정보
container : 담는 그릇(기능을 담던, 정보를 담던, 객체를 담던)
또한 factory메서드를 통해 객체를 넘겨 받을때 Object타입으로 객체를 받게 됩니다.
그래서 명시적으로 형변환을 반드시 해주어야합니다!
해당 코드에서는 (MessageBean)타입으로 형 변환 해주었습니다!
생성(Beans.xml)과 사용(MTest.java)이 구분되어있다고 할수있겠죠.
이렇게 프로그램의 제어 흐름 구조가 뒤바뀌는 것 개념을 IoC(Inversion of Controll)이라고 합니다.
