Java 관련/Spring Legecy

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

씨네 2022. 3. 10. 08:53
728x90

스프링의 특징 중 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)이라고 합니다.

728x90