본문 바로가기
지식공유/Spring Framwork

Spring IoC(Spring/Spring Boot/Java/IoC/backend/제어의역행/자바/스프링/스프링부트)

by 시간기억자 2024. 8. 30.
반응형

스프링(Spring) IoC(제어의 역행)

IOC

  • IoC(Inversion Of Control) : 제어의 역행
  • IoC의 개념을 적용함으로 인해 얻을 수 있는 장점 : Container 기능을 제공하여 객체간의 결합도를 떨어뜨릴 수 있다.

  • xyz.itwill01.old(패키지) ⇒ 결합도 높은 버전
  • helloMessageObject(클래스)  //  MessagePrintObject(클래스)  //  MessagePrintApp(클래스)
  • HiMessageObject(클래스)



  • 클래스 하나가 바뀌니 그 클래스와 관계있는 다른 클래스도 모두 바꾸어줘야 한다.
    결합도가 높아서 유지보수가 힘들어진다.
  • 결합도를 낮추기위해 인터페이스를 이용하거나 팩토리 클래스를 이용하는거다.


  • xyz.itwill02.factory(패키지) ⇒ 결합도 낮은 버전
  • helloMessageObject(클래스)  // MessageObject(인터페이스)  //  MessageObjectFactory(팩토리 클래스)  //  MessagetPrintObjec(클래스)  //  MessagePrintApp(클래스)
  • HiMessageObject(클래스)

  • Factory 클래스에 의해 객체로 생성되어 제공될 클래스 - 인터페이스를 상속받아 작성
    (팩토리 클래스 쓰려면 꼭 인터페이스를 상속받아야 한다.)

 

MessageObject
(인터페이스)


MessageObjectFactory
(팩토리 클래스)


Spring IoC

  • IoC 개념
    : 개발자가 new 연산자로 객체를 직접 만드는게 아니라, Container에게 객체를 대신 만들어달라고 해서 객체간의 결합도를 떨어뜨리는 개념이라고 생각하면 된다.
  • Spring의 가장 기본적인 기능은 Container 기능이라 할 수 있다.
  • 객체를 누군가가 대신 생성해준다면 생성 결합을 줄여줌으로써 결합도를 낮출 수 있다.
  • 결합도를 낮추기 위해서는
    → 인터페이스 사용 ( 메소드 오버라이드에 의한 다형성)
    → Factory 클래스 사용(Factory 클래스 만들때도 인터페이스 만들어야 한다 → 메소드 오버라이드에 의한 다형성)

  • 제어의 역행 의미는 다른 누군가가 대신 객체를 만들어주면 그 객체를 제공받아 프로그램을 만드는 개념이다.
  • 원래 프로그래머가 명령을 통해 객체를 생성, 사용, 소멸시키는데
    그걸 컨테이너 기능을 통해 객체를 생성, 사용, 소멸시키는 것이다
  • 그러기 위해서는 Factory 클래스가 필요하다.
  • 컨테이너는 객체 생성이 가능하고, 필요시 관계도 형성시킬 수 있고 소멸도 시킬 수 있다.
    (컨테이너는 팩토리 클래스보다 한단계 상위 단계라고 생각하면 된다.)

 

Spring Container

  • xyz.itwill03.spring(패키지)
  • MessageObject(인터페이스)
  • HelloMessageObject(클래스)  //  MessagePrintObject(클래스)  // MessagePrintApp(클래스)  //  HiMessageObject(클래스)
  • 03_message.xml

  • 인터페이스가 필수는 아니지만, 인터페이스가 있어야지 결합도를 낮출 수 있다.

  • ApplicationContext 객체 : 스프링 컨테이너(Spring Container)
  • ApplicationContext context=new ClassPathXmlApplicationContext("03_message.xml");
  • 03_message.xml 파일 만들때 아래와 같이 생성
  • XML 파일은 아래의 방법으로 생성하면 된다.
  • 스프링 컨테이너(Spring Container)는 환경설정파일(Spring Bean Configuration File - XML파일)로부터 클래스를 제공받아 객체를 생성하여 관리
    → Spring Bean : 스프링 컨테이너에 의해 관리되는 객체(클래스)
    → 스프링 컨테이너는 클래스를 문자열로 제공받아 리플렉션(Reflection) 기술을 사용해 객체 생성
  • bean 엘리먼트를 사용해 스프링 컨테이너에게 클래스를 제공하여 Spring Bean으로 사용되도록 설정
  • bean 엘리먼트의 하위 엘리먼트를 사용하여 Spring Bean에 대한 의존관계 설정

  • HelloMessageObject를 HiMessageObject로 바꾸고 싶으면 XML  파일만 고치면 된다.
  • 클래스가 바뀌어도 프로그램을 바꿀 필요 없이 XML 파일만 고치면 되는거다.

 

 

new 연산자로 객체를 만들어서 서로 관계를 만들어 놓을경우,

처음 HelloMessageObject 클래스로 프로그램 만든 다음에, 나중에 HiMessageObject 클래스로 바꿀 경우 모두 다 바꿔야 한다.
그 결합도를 낮추기 위한 방법인 것이다.

 

public interface MessageObject {
	String getMessage();
}
public class HelloMessageObject implements MessageObject {
	@Override
	public String getMessage() {
		return "Hello!!!";
	}
}
public class MessagePrintObject {
	//MessageObject 인터페이스를 상속받은 자식클래스의 객체를 저장하기 위한 필드
	//=> 필드에 객체를 저장하기 위해 생성자 또는 Setter 메소드를 작성 - 포함관계(의존관계)로 만들수있다
	//=> 필드에 객체를 저장해야만 필드에 저장된 객체를 참조해 메소드를 호출할 수 있다.
	private MessageObject object;
	
	//필드에 대한 Setter, Getter 생성
	public MessageObject getObject() {
		return object;
	}

	public void setObject(MessageObject object) {
		this.object = object;
	}
	
	public void messagePrint() {
		//필드에 객체가 저장되어 있지 않은 경우 NullPointerException 발생
		String message=object.getMessage();
		System.out.println("message = "+message);
	}
	
	
}
public class MessagePrintApp {
	public static void main(String[] args) {
		/*
		//HelloMessageObject object=new HelloMessageObject();
		HiMessageObject object=new HiMessageObject();
		MessagePrintObject print=new MessagePrintObject();
		//매개변수에 객체를 전달하여 필드에 저장 - 포함관계(의존관계) 구현
		print.setObject(object);
		print.messagePrint();
		*/
		
		//Spring Container 사용하면 Setter 메소드 만들어서 관계를 구현할 필요가 없다.
		
		//ApplicationContext(인터페이스) 객체 : 스프링 컨테이너(Spring Container) 기능을 제공하기 위한 객체
		//=> Spring Bean Configuration File(XML)을 제공받아 객체(Spring Bean)를 생성하여 관리한다.
		ApplicationContext context=new ClassPathXmlApplicationContext("03_message.xml");
		//ClassPath : 자바가 가져다 쓸 수 있는 Build Path 폴더에서
		//Xml : XML 파일들을 제공받아
		//ApplicationContext 프로그램을 만든다.
		
		MessagePrintObject print=(MessagePrintObject)context.getBean("messagePrintObject");
		print.messagePrint();
		
		//ApplicationContext 객체 제거 - 스프링 컨테이너 소멸
		//=> 스프링 컨테이너가 관리하는 모든 객체(Spring Bean)도 소멸
		//Garbage 콜렉터가 나중에 없애줘서 꼭 할필요는 없지만 그래도 했음.
		((ClassPathXmlApplicationContext)context).close();
		
	}
}
<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 https://www.springframework.org/schema/beans/spring-beans.xsd">
	<!-- 스프링 컨테이너(Spring Container)는 환경설정파일(Spring Bean Configuration File - XML파일)로부터
	클래스를 제공받아 객체를 생성하여 관리 -->
	<!-- => Spring Bean : 스프링 컨테이너에 의해 관리되는 객체(클래스) -->
	<!-- => 스프링 컨테이너는 클래스를 문자열로 제공받아 리플렉션(Reflection) 기술을 사용해 객체 생성 -->
	
	<!-- bean 엘리먼트를 사용해 스프링 컨테이너에게 클래스를 제공하여 Spring Bean으로 사용되도록 설정 -->
	<bean class="xyz.itwill03.spring.HelloMessageObject" id="helloMessageObject"/>
	<bean class="xyz.itwill03.spring.HiMessageObject" id="hiMessageObject"/>
	
	<!-- bean 엘리먼트의 하위 엘리먼트를 사용하여 Spring Bean에 대한 의존관계 설정 -->
	<bean class="xyz.itwill03.spring.MessagePrintObject" id="messagePrintObject">
		<!-- <property name="object" ref="helloMessageObject"/> -->
		<property name="object" ref="hiMessageObject"/>
	</bean>
</beans>

 

  • ApplicationContext(인터페이스) 객체 : 스프링 컨테이너(Spring Container) 기능을 제공하기 위한 객체
    → Spring Bean Configuration File(XML)을 제공받아 객체(Spring Bean)를 생성하여 관리한다.
  • ApplicationContext context=new ClassPathXmlApplicationContext(“xml 파일 경로”);

 

반응형

댓글