IoC (제어의 역행)

woom·2023년 2월 10일
0

Framework

목록 보기
7/20
post-thumbnail

🌼 IoC (제어의 역행)

  • IoC(Inversion Of Control) : 제어의 역행

    • IoC의 개념을 적용함으로 인해 얻을 수 있는 장점 : Container 기능을 제공하여 객체간의 결합도를 떨어뜨릴 수 있음
    • factory : 객체 생성 생성하여 제공하고 container : 객체 생성하여 제공하고 소멸 가능

💡 getter setter 메소드 출력시 오류 생길 경우

  1. Window → Preferences → Java → Editor → Mark Occurrences → Mark Occurences 체크
  1. Toggle Mark Occurence icon 클릭

📕 인터페이스

  • 인터페이스를 상속받은 클래스는 반드시 인터페이스에 작성된 모든 추상메소드를 오버라이드 선언

    • 인터페이스를 상속받은 클래스에 메소드 작성 규칙 제공
    • 인터페이스 : 작업지시서 역활
  • 인터페이스로 참조변수를 생성하면 참조변수에는 인터페이스를 상속받은 모든 자식클래스의 객체 저장 가능

    • 인터페이스로 생성된 참조변수로 추상메소드를 호출하면 참조변수에 저장된 자식클래스 객체의 오버라이드 메소드 호출
    • 오버라이드에 의한 다형성 : 객체간의 결합도 감소
public interface MessageObject {
	String getMessage();
}




🐣 인터페이스 상속

  • Factory 클래스에 의해 생성되어 제공되는 클래스는 반드시 인터페이스를 상속받아 작성
package xyz.itwill02.factory;

public class HelloMessageObject implements MessageObject {
	@Override
	public String getMessage() {
		return "Hello!!!";
	}
}





📙 Factory 클래스

  • Factory 디자인 패턴을 이용하여 작성된 클래스 : Factory 클래스 또는 Provider 클래스
    • 프로그램 개발에 필요한 객체를 생성하여 제공하는 기능의 클래스
    • 컨테이너(Container)
  • 매개변수로 전달받은 값을 비교하여 프로그램 개발에 필요한 객체를 생성하여 반환하는 메소드
package xyz.itwill02.factory;

public class MessageObjectFactory {
	private static MessageObjectFactory _factory;
	
	private MessageObjectFactory() {
		// TODO Auto-generated constructor stub
	}
	
	static {
		_factory=new MessageObjectFactory();
	}
	
	public static MessageObjectFactory getFactory() {
		return _factory;
	}
	
	//Factory 클래스에 의해 제공될 객체를 구분하기 위한 상수(Constant)
	public static final int HELLO_MSG=1;
	public static final int HI_MSG=2;
	
	//매개변수로 전달받은 값을 비교하여 프로그램 개발에 필요한 객체를 생성하여 반환하는 메소드
	public MessageObject getMessageObject(int messageObject) {
		MessageObject object=null;
		switch (messageObject) {
		case HELLO_MSG:
			object=new HelloMessageObject();
			break;
		case HI_MSG:
			object=new HiMessageObject();
			break;	
		}
		return object;
	}
}





🐣 Factory클래스 메소드 호출

  • 객체를 직접 생성하여 메소드 호출하면 객체간의 결합도가 높아 유지보수의 효율성 감소

  • 프로그램 작성에 필요한 객체를 Factory 클래스로부터 제공받아 메소드 호출

    • IoC(Inversion of Control) : 객체간의 결합도를 낮춰 유지보수의 효율성 증가
  • 인터페이스로 생성된 참조변수의 추상메소드를 호출한 경우 참조변수에 저장된 자식 클래스 객체의 오버라이드 메소드 호출

    • 묵시적 객체 형변환 : 오버라이드에 의한 다형성

package xyz.itwill02.factory;

public class MessagePrint {
	public void messagePrint() {
		//객체를 직접 생성하여 메소드 호출 - 객체간의 결합도가 높아 유지보수의 효율성 감소
		//MessageObject object=new HelloMessageObject();
		
		//프로그램 작성에 필요한 객체를 Factory 클래스로부터 제공받아 메소드 호출 
		// => IoC(Inversion of Control) : 객체간의 결합도를 낮춰 유지보수의 효율성 증가
		//MessageObject object=MessageObjectFactory.getFactory().getMessageObject(1);
		MessageObject object=MessageObjectFactory.getFactory().getMessageObject(2);
		
		//인터페이스로 생성된 참조변수의 추상메소드를 호출한 경우 참조변수에 저장된 자식 클래스
		//객체의 오버라이드 메소드 호출 - 묵시적 객체 형변환 : 오버라이드에 의한 다형성
		String message=object.getMessage();
		System.out.println("message = "+message);
	}
}





🐣 앱 실행

package xyz.itwill02.factory;

public class MessagePrintApp {
	public static void main(String[] args) {
		MessagePrint print=new MessagePrint();
		print.messagePrint();
	}
}





📌 환경설정 파일 생성

  • Spring Bean Configuration File(환경설정파일) 생성 방법
  1. Project → src/main/resources 클릭 후 마우스 오른쪽 버튼 → New → Spring Bean Configuration File 클릭

  1. File name 작성 후 Next

  1. 상단 beans 체크 → 하단 https://www.springframework.org/schema/beans/spring-beans.xsd 체크 후 Finish


🐣 MessagePrint 클래스

  • MessageObject 인터페이스를 상속받은 자식클래스의 객체를 저장하기 위한 필드

    • 필드에 객체를 저장해야만 포함관계 성립 (포함관계의 클래스에 작성된 메소드 호출 가능)
    • private MessageObject object;
package xyz.itwill03.spring;

public class MessagePrint {
	//MessageObject 인터페이스를 상속받은 자식클래스의 객체를 저장하기 위한 필드
	// => 필드에 객체를 저장해야만 포함관계 성립 - 포함관계의 클래스에 작성된 메소드 호출 가능
	private MessageObject object;

	public MessageObject getObject() {
		return object;
	}

	public void setObject(MessageObject object) {
		this.object = object;
	}
	
	public void messagePrint() {
		String message=object.getMessage();
		System.out.println("message = "+message);
	}
}





📒 환경설정파일1

  • 스프링 컨테이너는 환경설정파일(Spring Bean Configuration File - XML)로부터 클래스를 제공받아 객체를 생성하여 관리

    • Spring Bean : 스프링 컨테이너에 의해 관리되는 객체(클래스)
    • 스프링 컨테이너는 리플렉션(Reflection) 기술을 사용하여 객체 생성
  • bean 엘리먼트를 사용하여 스프링 컨테이너에게 Spring Bean으로 사용될 클래스 제공

    • bean 엘리먼트의 하위 엘리먼트를 사용하여 Spring Bean에 대한 포함관계 설정 (의존성 주입)
    • <property name="object" ref="hiMessageObject"/>

<?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 https://www.springframework.org/schema/beans/spring-beans.xsd">
	<!-- 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.MessagePrint" id="messagePrint">
		<!-- <property name="object" ref="helloMessageObject"/> -->
		<property name="object" ref="hiMessageObject"/>
	</bean>
</beans>






📗 앱 실행

  • Spring Container : Spring Framework에서 프로그램 작성에 필요한 객체를 관리하는 컴퍼넌트

    • spring container(factory class생성 필요 없음) 한테 사용하고자 하는 클래스를 전달하면 class의 객체를 생성해서 id라는 이름으로 만들어줘
  • 스프링 컨테이너(Spring Container)를 이용하여 객체를 생성하여 제공받아 사용

    • 프로그래머가 아닌 스프링 컨테이너가 객체 관리 (Spring IoC)
    • 스프링 컨테이너는 환경설정파일(Spring Bean Configuration File - XML)을 이용하여 객체의 생명주기(LifeCycle) 관리 및 객체간의 관계 설정
  • ApplicationContext 객체(스프링 컨테이너 기능을 제공하는 객체) 생성

    • Spring Bean Configuration File을 제공받아 Spring Bean를 생성하여 관리
    • ApplicationContext context=new ClassPathXmlApplicationContext("03_message.xml");
  • 스프링 컨테이너로부터 필요한 Spring Bean을 제공받아 저장

    • Spring Bean을 구분하기 위한 식별자(beanName 또는 beanId)를 전달
    • MessagePrint print=(MessagePrint)context.getBean("messagePrint");
  • 스프링 컨테이너 제거

    • ((ClassPathXmlApplicationContext)context).close();

package xyz.itwill03.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MessagePrintApp {
	public static void main(String[] args) {
		/*
		HelloMessageObject object=new HelloMessageObject();
		MessagePrint print=new MessagePrint();
		print.setObject(object);//포함관계 성립 - 필드에 HelloMessageObject 객체 저장
		print.messagePrint();
		*/

		//ApplicationContext 객체(스프링 컨테이너 기능을 제공하는 객체) 생성
		// => Spring Bean Configuration File을 제공받아 Spring Bean를 생성하여 관리
		ApplicationContext context=new ClassPathXmlApplicationContext("03_message.xml");
		
		//스프링 컨테이너로부터 필요한 Spring Bean를 제공받아 저장
		// => Spring Bean을 구분하기 위한 식별자(beanName 또는 beanId)를 전달 
		MessagePrint print=(MessagePrint)context.getBean("messagePrint");
		
		print.messagePrint();
		
		//스프링 컨테이너 제거
		((ClassPathXmlApplicationContext)context).close();
	}
}





🐣 CreateBean 클래스


package xyz.itwill04.bean;

public class CreateBean {
	public CreateBean() {
		System.out.println("### CreateBean 클래스의 기본 생성자 호출 ###");
	}
	
	public void display() {
		System.out.println("*** CreateBean 클래스의 display() 메소드 호출 ***");
	}
}





📒 환경설정파일2 (bean)

  • Spring Bean Configuration File를 여러개 작성하여 사용하는 이유

    • 하나의 Spring Bean Configuration File을 사용하여 Spring Bean를 설정할 경우 가독성 및 유지보수의 비효율성 증가
  • import : 다른 Spring Bean Configuration File의 Spring Bean 정보를 제공받아 포함하기 위한 엘리먼트

    • resource 속성 : 포함될 Spring Bean Configuration File의 경로를 속성값으로 설정
    • <import resource="03_message.xml"/>
  • Spring Bean : 스프링 컨테이너의 의해 관리(생성,사용,소멸)되는 객체(클래스)

  • bean : 스프링 컨테이너에게 Spring Bean 관련 정보를 제공하기 위한 엘리먼트

    • class 속성 : Spring Bean으로 등록되어 사용될 클래스를 속성값으로 설정 (필수)
      • class 속성값은 이클립스의 자동 완성 기능을 사용하여 작성 가능
    • id 속성 : Spring Bean를 구분하기 위한 식별자를 속성값으로 설정
      • id 속성 대신 name 속성을 사용하여 식별자 설정 가능
      • id 속성값은 클래스 이름(부모 인터페이스 이름)을 이용하여 설정하는 것을 권장
      • id 속성값은 class 속성이 설정되어 있는 경우 이클립스의 자동 완성 기능을 사용하여 작성 가능
    • <bean class="xyz.itwill04.bean.CreateBean" id="createBean"/>

<?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">
	<!-- import : 다른 Spring Bean Configuration File의 Spring Bean 정보를 제공받아 포함하기 위한 엘리먼트 -->
	<!-- resource 속성 : 포함될 Spring Bean Configuration File의 경로를 속성값으로 설정 -->
	<!-- <import resource="03_message.xml"/> -->
	
	<!-- bean : 스프링 컨테이너에게 Spring Bean 관련 정보를 제공하기 위한 엘리먼트 -->
	<!-- => Spring Bean : 스프링 컨테이너의 의해 관리(생성,사용,소멸)되는 객체(클래스) -->
	<!-- class 속성 : Spring Bean으로 등록되어 사용될 클래스를 속성값으로 설정 - 필수 -->
	<!-- => class 속성값은 이클립스의 자동 완성 기능을 사용하여 작성 가능 -->
	<!-- id 속성 : Spring Bean를 구분하기 위한 식별자를 속성값으로 설정 -->
	<!-- => id 속성 대신 name 속성을 사용하여 식별자 설정 가능 -->
	<!-- => id 속성값은 클래스 이름(부모 인터페이스 이름)을 이용하여 설정하는 것을 권장 -->
	<!-- => id 속성값은 class 속성이 설정되어 있는 경우 이클립스의 자동 완성 기능을 사용하여 작성 가능 -->
	<bean class="xyz.itwill04.bean.CreateBean" id="createBean"/>
</beans>





📗 bean객체의 초기화

  • 스프링 컨테이너는 환경설정파일(Spring Bean Configuration File - XML)을 제공받아 클래스의 객체(Spring Bean)를 관리

    • Spring Framework에서는 1. BeanFactory 객체 또는 2. ApplicationContext 객체로 스프링 컨테이너(Spring Container) 기능 제공
  1. BeanFactory 인터페이스를 상속받은 자식클래스로 객체를 생성 (BeanFactory 객체)
  • BeanFactory 객체를 생성할 때 Spring Bean Configuration File를 제공받아 스프링 컨테이너 생성 (스프링 컨테이너의 초기화 작업)
    • Spring Bean Configuration File의 파일 경로를 모두 표현하여 설정
    • BeanFactory 객체는 Spring Bean Configuration File에 등록된 클래스로 미리 객체를 생성하지 않고 Spring Bean 요청시 객체를 생성하여 제공
    • BeanFactory factory=new XmlBeanFactory(new FileSystemResource("src/main/resources/04-1_beanCreate.xml"));
  • BeanFactory.getBean(String beanName) : 스프링 컨테이너에서 Spring Bean를 구분하기 위한 식별자(beanId 또는 beanName)을 전달하여 객체(Spring Bean)를 생성하여 반환하는 메소드
    • Object 타입의 객체를 반환하므로 반드시 명시적 객체 형변환 사용
    • 전달받은 식별자(beanName)에 대한 Spring Bean이 없는 경우 NoSuchBeanDefinitionException 발생
  1. ApplicationContext 인터페이스를 상속받은 자식클래스로 객체를 생성 (ApplicationContext 객체)
  • ApplicationContext 객체를 생성할 때 Spring Bean Configuration File를 제공받아 스프링 컨테이너 생성 (스프링 컨테이너의 초기화 작업)
    • 클래스가 참조 가능한 디렉토리(ClassPath)에 있는 Spring Bean Configuration File로 설정
    • ApplicationContext 객체는 Spring Bean Configuration File에 등록된 클래스로 미리 객체를 생성하여 Spring Bean 요청시 제공
    • ApplicationContext context=new ClassPathXmlApplicationContext("04-1_beanCreate.xml");
  • DL(Dependency Lookup) : 스프링 컨테이너로부터 필요한 Spring Bean을 검색하여 제공하는 기능 (getbean)
  • ApplicationContext.getBean(String beanName) : 스프링 컨테이너에서 Spring Bean를 구분하기 위한 식별자(beanName)을 전달하여 객체(Spring Bean)를 반환하는 메소드
    • CreateBean bean2=(CreateBean)context.getBean("createBean");
  • ClassPathXmlApplicationContext.close() : ApplicationContext 객체를 제거하는 메소드
    • 스프링 컨테이너에 의해 관리되는 모든 객체(Spring Bean) 자동 소멸
    • ((ClassPathXmlApplicationContext)context).close();


package xyz.itwill04.bean;

@SuppressWarnings("deprecation")
public class CreateBeanApp {
	public static void main(String[] args) {
		System.out.println("1.BeanFactory 객체를 생성하여 스프링 컨테이너로 사용");
		System.out.println("================== Spring Container 초기화 전 ==================");
		//BeanFactory 인터페이스를 상속받은 자식클래스로 객체를 생성 - BeanFactory 객체
		// => BeanFactory 객체를 생성할 때 Spring Bean Configuration File를 제공받아 스프링 
		//컨테이너 생성 - 스프링 컨테이너의 초기화 작업 
		// => Spring Bean Configuration File의 파일 경로를 모두 표현하여 설정 
		// => BeanFactory 객체는  Spring Bean Configuration File에 등록된 클래스로 미리 객체를 
		//생성하지 않고 Spring Bean 요청시 객체를 생성하여 제공
		BeanFactory factory=new XmlBeanFactory(
				new FileSystemResource("src/main/resources/04-1_beanCreate.xml"));
		System.out.println("================== Spring Container 초기화 후 ==================");
		//BeanFactory.getBean(String beanName) : 스프링 컨테이너에게 Spring Bean를 구분하기 위한 
		//식별자(beanId 또는 beanName)을 전달하여 객체(Spring Bean)를 생성하여 반환하는 메소드
		// => Object 타입의 객체를 반환하므로 반드시 명시적 객체 형변환 사용
		// => 전달받은 식별자(beanName)에 대한 Spring Bean이 없는 경우 NoSuchBeanDefinitionException 발생
		CreateBean bean1=(CreateBean)factory.getBean("createBean");
		bean1.display();
		System.out.println("================================================================");
		System.out.println("2.ApplicationContext 객체를 생성하여 스프링 컨테이너로 사용");
		System.out.println("================== Spring Container 초기화 전 ==================");
		//ApplicationContext 인터페이스를 상속받은 자식클래스로 객체를 생성 - ApplicationContext 객체
		// => ApplicationContext 객체를 생성할 때 Spring Bean Configuration File를 제공받아  
		//스프링 컨테이너 생성 - 스프링 컨테이너의 초기화 작업 
		// => 클래스가 참조 가능한 디렉토리(ClassPath)에 있는 Spring Bean Configuration File로 설정
		// => ApplicationContext 객체는  Spring Bean Configuration File에 등록된 클래스로 미리
		//객체를 생성하여 Spring Bean 요청시 제공
		ApplicationContext context=new ClassPathXmlApplicationContext("04-1_beanCreate.xml");
		System.out.println("================== Spring Container 초기화 후 ==================");
		//DL(Dependency Lookup) : 스프링 컨테이너로부터 필요한 Spring Bean를 검색하여 제공하는 기능
		//ApplicationContext.getBean(String beanName) : 스프링 컨테이너에게 Spring Bean를 구분
		//하기 위한 식별자(beanName)을 전달하여 객체(Spring Bean)를 반환하는 메소드
		CreateBean bean2=(CreateBean)context.getBean("createBean");
		bean2.display();
		
		//ClassPathXmlApplicationContext.close() : ApplicationContext 객체를 제거하는 메소드
		// => 스프링 컨테이너에 의해 관리되는 모든 객체(Spring Bean) 자동 소멸
		((ClassPathXmlApplicationContext)context).close();
		System.out.println("================================================================");
	}
}






🐣 InitDestroyBean class

package xyz.itwill04.bean;

public class InitDestroyMethodBean {
	public InitDestroyMethodBean() {
		System.out.println("### InitDestroyMethodBean 클래스의 기본 생성자 호출 ###");
	}
	
	//객체 생성 후 객체의 초기화 작업(필드의 초기값 설정)을 위해 한번만 자동 호출되는 메소드
	public void init() {
		System.out.println("*** InitDestroyMethodBean 클래스의 init() 메소드 호출 ***");
	}
	
	//객체 소멸 전 객체의 마무리 작업을 위해 한번만 자동 호출되는 메소드
	public void destroy() {
		System.out.println("*** InitDestroyMethodBean 클래스의 destroy() 메소드 호출 ***");
	}
	
	public void display() {
		System.out.println("*** InitDestroyMethodBean 클래스의 display() 메소드 호출 ***");
	}
}





🐣 LazyInitBean class

package xyz.itwill04.bean;

public class LazyInitBean {
	public LazyInitBean() {
		System.out.println("### LazyInitBean 클래스의 기본 생성자 호출 ###");
	}
}





🐣 Singleton class

  • 싱글톤 디자인 패턴을 적용하여 작성된 클래스
    • 싱글톤 클래스(Singleton Class)
    • 프로그램에 필요한 객체를 하나만 제공하기 위한 목적의 클래스 작성시 사용하는 디자인 패턴
package xyz.itwill04.bean;

public class FactoryMethodBean {
	private static FactoryMethodBean _bean;
	
	private FactoryMethodBean() {
		System.out.println("### FactoryMethodBean 클래스의 기본 생성자 호출 ###");
	}
	
	static {
		_bean=new FactoryMethodBean();
	}
	
	public static FactoryMethodBean getFactoryMethodBean() {
		System.out.println("*** FactoryMethodBean 클래스의 getFactoryMehodBean() 메소드 호출 ***");
		return _bean;
	}
}





📒 환경설정파일3 (속성)

  • init-method 속성 : 스프링 컨테이너에 의해 객체(Spring Bean)가 생성된 후 한번만 자동 호출되어 객체의 초기화 작업을 실행하기 위한 메소드의 이름을 속성값으로 설정
    • init-method 속성값은 이클립스의 자동 완성 기능을 사용하여 작성 가능
  • destroy-method 속성 : 스프링 컨테이너에 의해 객체(Spring Bean)가 소멸되기 전 한번만 자동 호출되어 객체의 마무리 작업을 실행하기 위한 메소드의 이름을 속성값으로 설정
    • destroy-method 속성값은 이클립스의 자동 완성 기능을 사용하여 작성 가능
  • lazy-init 속성 : false 또는 true 중 하나를 속성값으로 설정
    • false(기본) : 스프링 컨테이너를 초기화할 때 객체(Spring Bean)를 미리 생성
    • true : 스프링 컨테이너로부터 Spring Bean를 제공받기 위해 getBean() 메소드를 호출할 때 객체 생성
  • 스프링 컨테이너는 Spring Bean Configuration File에 등록된 모든 클래스를 리플렉션 기술을 사용하여 미리 객체(Spring Bean)로 생성
    • 리플렉션 기술(힙 영역에 로드된 Class타입의 객체를 통해, 원하는 클래스의 인스턴스를 생성할 수 있도록 지원하고, 인스턴스의 필드와 메소드를 접근 제어자와 상관 없이 사용할 수 있도록 지원하는 API)을 사용하면 클래스의 접근 지정자에 상관없이 모든 요소에 접근 가능
    • 생성자가 은닉화 선언되어 있어도 스프링 컨테이너는 클래스의 생성자로 객체 생성
    • Spring Bean Configuration File에 등록된 싱글톤 클래스는 클래스가 메모리에 로딩된 후 정적영역의 명령을 실행하여 객체를 생성하고 스프링 컨테이너에 의해 객체를 다시 생성
    • 싱글톤 클래스에 의해 객체가 2개 생성 → 싱글톤 클래스의 작성 규칙 위반
  • factory-method 속성 : 싱글톤 클래스에서 객체를 반환하는 메소드의 이름을 속성값으로 설정
    • 스프링 컨테이너에 의해 객체를 생성하지 않고 정적영역의 명령으로 객체를 생성하여 사용
      -<bean class="xyz.itwill04.bean.FactoryMethodBean" factory-method="getFactoryMethodBean"/> </beans>
  • 스프링 컨테이너는 bean 엘리먼트의 선언 순서대로 등록된 클래스를 객체로 생성
  • depends-on 속성 : Spring Bean를 구분하기 위한 식별자(beanName)를 속성값으로 설정
    • bean 엘리먼트에 등록된 클래스를 객체로 생성하기 전에 depends-on 속성값으로 설정된 Spring Bean의 클래스를 객체로 미리 생성
  • scope 속성 : singleton(기본), prototype, request, session 중 하나를 속성값으로 설정
    • singleton 또는 prototype : 객체(Spring Bean)의 생성 갯수를 설정하는 속성값
    • singleton : 스프링 컨테이너가 bean 엘리먼트에 등록된 클래스로 객체를 하나만 생성하여 제공
    • prototype : 스프링 컨테이너가 bean 엘리먼트에 등록된 클래스로 객체를 여러개 생성하여 제공
    • scope 속성값을 [prototype]으로 설정할 경우 lazy-init 속성값을 반드시 [true]로 설정
    • request 또는 session : 객체의 사용범위를 설정하는 속성값 (웹프로그램 작성시에만 사용)

<?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">

	<!-- init-method 속성 : 스프링 컨테이너에 의해 객체(Spring Bean)가 생성된 후 한번만 자동
	호출되어 객체의 초기화 작업을 실행하기 위한 메소드의 이름을 속성값으로 설정 -->
	<!-- => init-method 속성값은 이클립스의 자동 완성 기능을 사용하여 작성 가능 -->
	<!-- destroy-method 속성 : 스프링 컨테이너에 의해 객체(Spring Bean)가 소멸되기 전 한번만 
	자동 호출되어 객체의 마무리 작업을 실행하기 위한 메소드의 이름을 속성값으로 설정 -->
	<!-- => destroy-method 속성값은 이클립스의 자동 완성 기능을 사용하여 작성 가능 -->
	<bean class="xyz.itwill04.bean.InitDestroyMethodBean" id="initDestroyMethodBean"
		init-method="init" destroy-method="destroy"/>

	<!-- lazy-init 속성 : false 또는 true 중 하나를 속성값으로 설정 -->
	<!-- => false(기본) : 스프링 컨테이너를 초기화할 때 객체(Spring Bean)를 미리 생성  -->
	<!-- => true : 스프링 컨테이너로부터 Spring Bean를 제공받기 위해 getBean() 메소드를 호출할 때 객체 생성 -->
	<bean class="xyz.itwill04.bean.LazyInitBean" id="lazyInitBean" lazy-init="true"/>
	
	<!-- 스프링 컨테이너는 Spring Bean Configuration File에 등록된 모든 클래스를 리플렉션
	기술을 사용하여 미리 객체(Spring Bean)로 생성 -->
	<!-- => 리플렉션 기술을 사용하면 클래스의 접근 지정자에 상관없이 모든 요소에 접근 가능 -->
	<!-- => 생성자가 은닉화 선언되어 있어도 스프링 컨테이너는 클래스의 생성자로 객체 생성 -->
	<!-- Spring Bean Configuration File에 등록된 싱글톤 클래스는 클래스가 메모리에 로딩된 후
	정적영역의 명령을 실행하여 객체를 생성하고 스프링 컨테이너에 의해 객체를 다시 생성 -->
	<!-- => 싱글톤 클래스에 의해 객체가 2개 생성 - 싱글톤 클래스의 작성 규칙 위반 -->
	<!-- factory-method 속성 : 싱글톤 클래스에서 객체를 반환하는 메소드의 이름을 속성값으로 설정 -->
	<!-- => 스프링 컨테이너에 의해 객체를 생성하지 않고 정적영역의 명령으로 객체를 생성하여 사용 -->
	<bean class="xyz.itwill04.bean.FactoryMethodBean" factory-method="getFactoryMethodBean"/>
	
	<!-- 스프링 컨테이너틑 bean 엘리먼트의 선언 순서대로 등록된 클래스를 객체로 생성 -->
	<!-- depends-on 속성 : Spring Bean를 구분하기 위한 식별자(beanName)를 속성값으로 설정 -->
	<!-- => bean 엘리먼트에 등록된 클래스를 객체로 생성하기 전에 depends-on 속성값으로 설정된 
	Spring Bean의 클래스를 객체로 미리 생성 -->
	<bean class="xyz.itwill04.bean.DependsOnOneBean" depends-on="dependsOnTwoBean"/>
	<bean class="xyz.itwill04.bean.DependsOnTwoBean" id="dependsOnTwoBean"/>
	
	<!-- scope 속성 : singleton(기본), prototype, request, session 중 하나를 속성값으로 설정 -->
	<!-- singleton 또는 prototype : 객체(Spring Bean)의 생성 갯수를 설정하는 속성값 -->
	<!-- => singleton : 스프링 컨테이너가 bean 엘리먼트에 등록된 클래스로 객체를 하나만 생성하여 제공 -->
	<!-- => prototype : 스프링 컨테이너가 bean 엘리먼트에 등록된 클래스로 객체를 여러개 생성하여 제공 -->
	<!-- => scope 속성값을 [prototype]으로 설정할 경우 lazy-init 속성값을 반드시 [true]로 설정 -->
	<!-- request 또는 session : 객체의 사용범위를 설정하는 속성값 - 웹프로그램 작성시에만 사용 -->
	<bean class="xyz.itwill04.bean.ScopeBean" id="singletonBean" lazy-init="true" scope="singleton"/>
	<bean class="xyz.itwill04.bean.ScopeBean" id="prototypeBean" lazy-init="true" scope="prototype"/>
</beans>





📗 앱 실행

  • ApplicationContext.getBean(String beanName) : 스프링 컨테이너에게 Spring Bean를 구분하기 위한 식별자(beanName)을 전달하여 객체(Spring Bean)를 반환하는 메소드

    • Object 타입의 객체를 반환하므로 반드시 명시적 객체 형변환 사용
    • ApplicationContext.getBean(String beanName, Class<T> clazz) : 스프링 컨테이너에게 Spring Bean을 구분하기 위한 식별자(beanName)와 Class 객체(Clazz)를 전달하여 원하는 클래스 타입의 객체(Spring Bean)로 변환하여 반환하는 메소드
    • InitDestroyMethodBean bean=context.getBean("initDestroyMethodBean", InitDestroyMethodBean.class);



package xyz.itwill04.bean;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class BeanAttributeApp {
	public static void main(String[] args) {
		System.out.println("================== Spring Container 초기화 전 ==================");
		ApplicationContext context=new ClassPathXmlApplicationContext("04-2_beanAttribute.xml");
		System.out.println("================== Spring Container 초기화 후 ==================");
		//ApplicationContext.getBean(String beanName) : 스프링 컨테이너에게 Spring Bean를 구분
		//하기 위한 식별자(beanName)을 전달하여 객체(Spring Bean)를 반환하는 메소드
		// => Object 타입의 객체를 반환하므로 반드시 명시적 객체 형변환 사용
		//InitDestroyMethodBean bean=(InitDestroyMethodBean)context.getBean("initDestroyMethodBean");
		
		//ApplicationContext.getBean(String beanName, Class<T> clazz) : 스프링 컨테이너에게 
		//Spring Bean를 구분하기 위한 식별자(beanName)와 Class 객체(Clazz)를 전달하여 원하는 
		//클래스 타입의 객체(Spring Bean)로 변환하여 반환하는 메소드
		InitDestroyMethodBean bean=context.getBean("initDestroyMethodBean", InitDestroyMethodBean.class);
		
		//bean.init();
		bean.display();
		//bean.destroy();
		
		System.out.println("================================================================");
		context.getBean("lazyInitBean", LazyInitBean.class);
		System.out.println("================================================================");
		ScopeBean bean1=context.getBean("singletonBean",ScopeBean.class);
		ScopeBean bean2=context.getBean("singletonBean",ScopeBean.class);
		ScopeBean bean3=context.getBean("singletonBean",ScopeBean.class);
		
		System.out.println("bean1 = "+bean1);
		System.out.println("bean2 = "+bean2);
		System.out.println("bean3 = "+bean3);
		System.out.println("================================================================");
		ScopeBean bean4=context.getBean("prototypeBean",ScopeBean.class);
		ScopeBean bean5=context.getBean("prototypeBean",ScopeBean.class);
		ScopeBean bean6=context.getBean("prototypeBean",ScopeBean.class);
		
		System.out.println("bean4 = "+bean4);
		System.out.println("bean5 = "+bean5);
		System.out.println("bean6 = "+bean6);
		System.out.println("================================================================");
		((ClassPathXmlApplicationContext)context).close();
		System.out.println("================================================================");
	}
}





🐣 AnnotationBean class

package xyz.itwill04.bean;

public class AnnotationBean {
	public AnnotationBean() {
		System.out.println("### AnnotationBean 클래스의 기본 생성자 호출 ###");
	}
	
	public void display() {
		System.out.println("*** AnnotationBean 클래스의 display() 메소드 호출 ***");
	}
}





📒 환경설정 (Annotation)

  • context 네임스페이스의 spring-context.xsd 파일에 의해 제공되는 엘리먼트

  • component-scan : 스프링 어노테이션(Spring Annotation)을 스프링 컨테이너가 검색하여 처리할 수 있도록 설정하는 엘리먼트
    • base-package 속성 : 스프링 컨테이너가 스프링 어노테이션을 사용한 클래스를 검색하기 위한 패키지를 속성값으로 설정

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

	<!-- <bean class="xyz.itwill04.bean.AnnotationBean" id="annotationBean"/> -->
	
	<!-- component-scan : 스프링 어노테이션(Spring Annotation)을 스프링 컨테이너가 검색하여
	처리할 수 있도록 설정하는 엘리먼트 -->
	<!-- => context 네임스페이스의 spring-context.xsd 파일에 의해 제공되는 엘리먼트 -->
	<!-- base-package 속성 : 스프링 컨테이너가 스프링 어노테이션을 사용한 클래스를 검색하기
	위한 패키지를 속성값으로 설정 -->
	<context:component-scan base-package="xyz.itwill04.bean"/>
</beans>





📘 @Configuration

  • @Configuration : 스프링 컨테이너에 의해 관리될 객체(Spring Bean)을 생성하여 반환하는 메소드가 선언될 클래스를 설정하기 위한 어노테이션

    • Spring Bean Configuration File과 유사한 기능을 제공하는 클래스로 설정하기 위해 사용
  • @Bean : Spring Bean으로 등록하기 위한 메소드에 설정하는 어노테이션

    • @Bean 어노테이션을 사용한 메소드는 클래스를 객체로 생성하여 반환 (Spring Bean)
    • bean 엘리먼트와 유사한 기능을 제공하는 어노테이션
    • 기본적으로 메소드의 이름을 Spring Bean의 식별자(beanName)으로 사용
    • @Bean 어노테이션의 name 속성을 사용하여 식별자 변경 가능

package xyz.itwill04.bean;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//@Configuration : 스프링 컨테이너에 의해 관리될 객체(Spring Bean)을 생성하여 반환하는 메소드가
//선언될 클래스를 설정하기 위한 어노테이션
@Configuration
public class AnnotationConfigurationBean {
	//@Bean : Spring Bean으로 등록하기 위한 메소드에 설정하는 어노테이션
	@Bean
	public AnnotationBean annotationBean() {
		return new AnnotationBean();
	}
}





📗 앱 실행 (@Configuration)

package xyz.itwill04.bean;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AnnotationBeanApp {
	public static void main(String[] args) {
		System.out.println("================== Spring Container 초기화 전 ==================");
		ApplicationContext context=new ClassPathXmlApplicationContext("04-3_beanAnnotation.xml");
		System.out.println("================== Spring Container 초기화 후 ==================");
		AnnotationBean bean=context.getBean("annotationBean",AnnotationBean.class);
		bean.display();
		System.out.println("================================================================");
		((ClassPathXmlApplicationContext)context).close();
	}
}





📘 @Component

  • @Component : 클래스를 스프링 컨테이너가 관리하는 Spring Bean으로 등록하는 어노테이션

    • 기본적으로 클래스의 이름을 Spring Bean의 식별자(beanName)으로 사용 (첫번째 문자는 소문자로 변환)
    • @Component 어노테이션의 value 속성을 사용하여 식별자 변경 가능
    • @Component 어노테이션에 value 속성외 다른 속성이 없는 경우 속성값만 설정 가능

package xyz.itwill04.bean;

import org.springframework.stereotype.Component;

//@Component : 클래스를 스프링 컨테이너가 관리하는 Spring Bean으로 등록하는 어노테이션
// => 기본적으로 클래스의 이름을 Spring Bean의 식별자(beanName)으로 사용 - 첫번째 문자는 소문자로 변환
// => @Component 어노테이션의 value 속성을 사용하여 식별자 변경 가능
// => @Component 어노테이션에 value 속성외 다른 속성이 없는 경우 속성값만 설정 가능
@Component("bean")
public class ComponentAnnotationBean {
	public ComponentAnnotationBean() {
		System.out.println("### ComponentAnnotationBean 클래스의 기본 생성자 호출 ###");
	}
	
	public void display() {
		System.out.println("*** ComponentAnnotationBean 클래스의 display() 메소드 호출 ***");
	}
}





📗 앱 실행 (@Component)

  • @Component 어노테이션의 value 속성을 사용하여 식별자 변경 가능


package xyz.itwill04.bean;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class ComponentAnnotationBeanApp {
	public static void main(String[] args) {
		System.out.println("================== Spring Container 초기화 전 ==================");
		ApplicationContext context=new ClassPathXmlApplicationContext("04-3_beanAnnotation.xml");
		System.out.println("================== Spring Container 초기화 후 ==================");
		//ComponentAnnotationBean bean=context.getBean("componentAnnotationBean",ComponentAnnotationBean.class);
		ComponentAnnotationBean bean=context.getBean("bean",ComponentAnnotationBean.class);
		bean.display();
		System.out.println("================================================================");
		((ClassPathXmlApplicationContext)context).close();
	}
}





profile
Study Log 📂

0개의 댓글