[Spring Framework] IoC 컨테이너

박은지·2022년 3월 4일
0

Spring Framework

목록 보기
3/3

IoC 컨테이너

  • IoC는 Inversion of Control의 약자로, 제어 역전이라는 의미
  • 일반적으로 프로그래밍을 작성할 때 프로그램이 흘러가는 흐름이나 생성되는 객체에 대한 제어권을 개발자가 만드는 개발자가 가지는 것과 달리 프레임워크가 가지는 것을 의미
  • 개발자가 코드의 흐름이나 객체 생성에 관련된 코드를 프로그래밍 코드에 직접 작성하는 것이 아닌 프레임워크가 사용하는 파일에 작성하면 이를 토대로 프레임워크가 객체를 생성하여 변환하고 코드가 동작하는 순서를 결정하게 된다는 의미

POJO Class

  • POJO는 Plan Old Java Object의 약자로, 자바 모델이나 기능, 프레임워크 등에 따르지 않고 홀로 독립적이며 단순한 기능만을 가지 객체들을 말한다.
  • 자바에서는 이러한 객체들을 Bean이라고 부른다.
  • POPO(PHP), POCO(닷넷 프레임워크), PODS(C++), POD(Perl)

Metadata

프로그램의 흐름에 관련된 정보

  • XML (스프링 초기에 사용한 방법)
  • Java

IoC 컨테이너 종류

BeanFactory

옛날 버전

  • 클래스를 통해 객체를 생성하고 이를 전달
  • 상속 등 객체 간의 관계를 형성하고 관리
  • 국제화 지원 등 문자열에 관련된 다양한 기능 제공
  • 리스너로 등록되어 있는 Bean에 이벤들를 방생사킬 수 있음
  • Bean에 관련된 설정을 위한 xml 파일은 즉시 로딩하면서 객체를 미리 생성해서 가지고 있음
  • ClassPathXmlApplicationContext
  • FileSystemXmlApplicationContext
  • XmlWebApplicationContext

ApplicationContext

현재 사용하는 버전

실습

  1. 새로운 Maven Project 생성
  2. pom.xml 작성
  3. src/main/java -> kr.co.softcampus.main 패키지 생성 -> MainClass.java 클래스 생성

BeanFactory (내부/외부)

  1. src/main/java -> kr.co.softcampus.config 패키지 생성 -> beans.xml 파일 생성
  2. src/main/java -> kr.co.softcampus.beans 패키지 생성 -> TestBean.java 클래스 생성
    6 . beans.xml에서 bean 정의

// 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 정의 -->				
	<!-- 객체 생성시 사용되는 클래스를 변경해야 하는 경우 beams.xml의 속성값만 변경해주면 된다. -->
	<!-- <bean id='hello' class="kr.co.softcampus.beans.HelloWorldEn"></bean> -->
	<bean id='t1' class="kr.co.softcampus.beans.TestBean"></bean>
</beans>
  1. TestBean.java 안에 생성자 만들기

// TestBean.java

package kr.co.softcampus.beans;

public class TestBean {
	
	public TestBean() {
		System.out.println("TestBean의 생성자");
	}

}

[BeanFactory 패키지 내부 : beans.xml 파일이 config 패키지 내부에 존재하는 경우]

  1. MainClass.java 에서 XML 데이터를 로딩하기
    test1();을 호출하였을 때 console창에는 로그만 찍히고 결과는 출력되지 않는다.
    XML 로딩하자마나 객체가 생성되는 것이 아니기 때문이다.
    ( XML BeanFactory는 XML 데이터를 로딩하면 기본적으로 정의되어진 Bean 객체들이 자동으로 생성되지 않는다. )

// MainClass.java

package kr.co.softcampus.main;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class MainClass {

	public static void main(String[] args) {
		test1();  // BeanFactory - 패키지 내부
	}
	
	// BeanFactory - 패키지 내부
	public static void test1() {
		ClassPathResource res = new ClassPathResource("kr/co/softcampus/config/beans.xml");
		XmlBeanFactory factory = new XmlBeanFactory(res); // IoC 컨테이너
	}
}
  1. MainClass.java 에서 Bean 가져오기 ( 객체 생성하기 )
package kr.co.softcampus.main;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;

import kr.co.softcampus.beans.TestBean;

public class MainClass {

	public static void main(String[] args) {
		// 로그만 찍히고 결과는 출력되지 않는다.
		// XML 로딩하자마자 객체가 생성되는 것이 아니기 떄문이다.
		
		test1();  // BeanFactory - 패키지 내부
	}
	
	
	/* XML BeanFactory는 XML 데이터를 로딩하면 기본적으로 정의되어진 Bean 객체들이 자동으로 생성되지 않는다. */
	
	// BeanFactory - 패키지 내부 ===========================
	// beans.xml 파일이 config 패키지 내부에 존재하는 경우
	public static void test1() {
		ClassPathResource res = new ClassPathResource("kr/co/softcampus/config/beans.xml");
		XmlBeanFactory factory = new XmlBeanFactory(res); // IoC 컨테이너
		
		// --- Bean 가져오기 (객체 생성) --- //
		// XML을 로딩할 때 객체가 생성되는 것이 아니라,getBean() 메소드로 객체를 가져올 때 객체가 생성되는 것!
		TestBean t1 = factory.getBean("t1", TestBean.class); // ID가 t1인 객체 생성
		System.out.printf("패키지 내부 t1 : %s\n", t1);
		
		// 같은ID를 가진 Bean 객체를 가져오면 또다시 객체 생성// 객체 생성
		TestBean t2 = factory.getBean("t1", TestBean.class); // ID가 t1인 객체 생성
		System.out.printf("패키지 내부 t2 : %s\n", t2);
		
		/* 생성자(TestBean의 생성자)는 한 번만 호출되었고, t1과 t2의 주소값은 같은 것을 확인할 수 있다.
		 * 
		 * Bean 객체를 가져올 때 객체가 이미 만들어져 있는 상황이 아니라면,
		 * 객체를 생성하고 주소값을 받는다.
		 * 이때, 이 주소값을 버리지 않고 가지고 있는다. 
		 * ---> 즉, 만들어진 객체를 "IoC 컨테이너"가 보관한다.
		 * 
		 * 그 다음 같은 ID로 객체를 가져오면 
		 * 이미 생성된 객체의 주소값을 받아 사용하는 것이다.
		 * */
	}
}

[BeanFactory 패키지 외부]

  1. MainClass.java 에서 XML 데이터를 로딩하기 & Bean 가져오기 ( 객체 생성하기 )
package kr.co.softcampus.main;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;

import kr.co.softcampus.beans.TestBean;

public class MainClass {

	public static void main(String[] args) {
		// 로그만 찍히고 결과는 출력되지 않는다.
		// XML 로딩하자마자 객체가 생성되는 것이 아니기 떄문이다.
		
		test1();  // BeanFactory - 패키지 내부
		test2();  // BeanFactory - 패키지 외부
	}
	
	
	/* XML BeanFactory는 XML 데이터를 로딩하면 기본적으로 정의되어진 Bean 객체들이 자동으로 생성되지 않는다. */
	
	// BeanFactory - 패키지 내부 =============================
	. . .
    
    // BeanFactory - 패키지 외부 =============================
	public static void test2() {
		// ---XML 데이터 로딩하기 (객체 생성 X) --- //
		FileSystemResource res = new FileSystemResource("beans.xml");
		XmlBeanFactory factory = new XmlBeanFactory(res);
		
		// --- Bean 가져오기 (객체 생성) --- //
		TestBean t1 = factory.getBean("t2", TestBean.class); // ID가 t2인 객체 생성
		System.out.printf("패키지 외부 t1 : %s\n", t1);
		
		TestBean t2 = factory.getBean("t2", TestBean.class); // ID가 t2인 객체 생성
		System.out.printf("패키지 외부 t2 : %s\n", t2);
		
	}

ApplicationContext (내부/외부)

ApplicationContext 내부

// MainClass.java

// ApplicationContext - 패키지 내부 =============================================================
	public static void test3() {
		// 별다른 설정을 해주지 않으면 beans.xml에 정의되어 있는 bean 객체들이 자동으로 생성된다. 
		// ( -> getBean 메소드를 호출할 떄 객체를 생성할 수 있고, 자동으로 생성되도록 지정할 수도 있음 )
		// 따라서 console 창 출력결과에 "TestBean의 생성자"이 출력된 것이다.
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("kr/co/softcampus/config/beans.xml");
		// 이미 만들어져 있는 객체의 주소값을 받아 객체를 만드는 것
		
		
		// --- Bean 가져오기 --- //
		TestBean t1 = ctx.getBean("t1", TestBean.class);  // ID가 t1인 객체 가져오기
		System.out.printf("ApplicationContext 패키지 외부 t1 : %s\n", t1);
		
		TestBean t2 = ctx.getBean("t1", TestBean.class);  // ID가 t1인 객체 가져오기
		System.out.printf("ApplicationContext 패키지 외부 t2 : %s\n", t2);
		
		ctx.close();
	}

ApplicationContext 외부

// MainClass.java

// ApplicationContext - 패키지 외부 =============================================================
	public static void test4() {
		FileSystemXmlApplicationContext ctx = new FileSystemXmlApplicationContext("beans.xml");
		
		// --- Bean 가져오기 --- //
		// 이미 만들어져 있는 객체의 주소값을 받아오는 것!
		TestBean t1 = ctx.getBean("t2", TestBean.class);  // ID가 t2인 객체 가져오기
		System.out.printf("ApplicationContext 패키지 외부 t1 : %s\n", t1);
				
		TestBean t2 = ctx.getBean("t2", TestBean.class);  // ID가 t2인 객체 가져오기
		System.out.printf("ApplicationContext 패키지 외부 t2 : %s\n", t2);
		
		ctx.close();
	}

0개의 댓글