Spring MVC, Sptring boot

Spring DI / IoC 를 설명하자

고인돌개발자 2021. 6. 19. 00:02

학습목표 : Spring DI / IoC 에 대한 개념을 이해해 보자


1. 자바 개념에서의 설명

<Java 구조에서 구성도>


<Class Uml>

<Java Class Uml>


자바소스 
  - 커피는 외부 클래스를 만들어서 사용한다.
  - 이때 외부 클래스를 사용하는걸 외부 클래스에 의존(Dependency) 한다고 한다. 

  - 자바 소스에서는 대부분 이렇게 사용하고자 하는 클래스를 new 로 생성해서 사용한다.

package team._springdi.ver1;

/**
 * Dependency 의존관계
 * 모닝커피를 마시자. 스벅에서
 * 주문을 한다. ( 메뉴는  1-아메리카노 , 2-돌체라떼, 3-카푸치노 ) * 
 * @author PC
 *
 */
public class Mver1 {
	 
	public static void main(String[] args) {
		
		/* 외부 클래스 커피에 의존(Dependency) 한다. 
		 * 외부에서 가져오지 말고, 직접 생성하여 만들자
		 */
		Americano ame 		= new Americano();
		Latte latte   		= new Latte();
		Cappuccino cappu	= new Cappuccino();
				
		int menu; // 커피 메뉴  :  1-아메리카노 , 2-돌체라떼, 3-카푸치노
		
		/* 커피 주문에 따른 메서드 호출 */
		menu=2; // 아메리카노 
		
		/* 커피 나왔어요.. */
		if(menu==1) {
			System.out.println(ame.toString());
		}else if(menu==2) {
			System.out.println(latte.toString());
		}else if(menu==3) {
			System.out.println(cappu.toString());
		}
	}
}
package team._springdi.ver1;

public class Americano {

	String taste = "깔끔한 맛";
	int price = 4000;
		
	@Override
	public String toString() {
		return "Americano [taste=" + taste + ", price=" + price + "]";
	}
}

----------------------------------------

package team._springdi.ver1;

public class Americano {

	String taste = "깔끔한 맛";
	int price = 4000;
		
	@Override
	public String toString() {
		return "Americano [taste=" + taste + ", price=" + price + "]";
	}
}

--------------------------------------

package team._springdi.ver1;

public class Americano {

	String taste = "깔끔한 맛";
	int price = 4000;
		
	@Override
	public String toString() {
		return "Americano [taste=" + taste + ", price=" + price + "]";
	}
}




그런데, 스벅이 장사가 잘돼서 바빠졌다.
모닝커피를 주문때마다 만들기가 힘들다.
그래서, 커피를 만들기 위한 준비물을 미리 준비해 두었다가
주문이 들어오면 바로 바로 가져다가 사용하면 효율적일것 같다.

2. Spring Framework 개념에서의 설명

<Spring Framework 구조에서 구성도>


Spring framework 소스 

  - 커피주문 html : 커피 주문을 받는 html 파일
  - 컨트롤서 : 컨트롤러는 단순하게 메뉴 접수를 받고 서비스에 업무를 지시한다.

  - 서비스는 메뉴를 접수받아서 접수받은 커피를 리턴해준다.

  - 커피메뉴 : 아메리카노, 카푸치노, 라떼 는 단순하게 빈으로 만든다.
                  (빈은 컨테이너에 들어가도록 @Component 어노테이션을 붙인다.


0. Spring boot 패키지 구조

<Project 구조>

 

1. 커피주문 coffee_order.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Morning Coffee</title>
</head>
<body>

<h2>스벅 - Morning Coffee .</h2><p>
안녕하세요. 메뉴를 선택해 주세요.<p>

<form action="/coffee/morning2" method="post">
<input type="radio" name="coffee" value="1" checked="checked"> <label>아메리카노</label><br>
<input type="radio" name="coffee" value="2"> <label>돌체라떼</label><br>
<input type="radio" name="coffee" value="3"> <label>카푸치노</label><br>

<p>
<input type="submit" value="커피주문">
</form>

</body>
</html>

  

2. 컨트롤러 - Ccounter2.java

package com.study.demo._team.di_ioc.controller;

/**
 * 모닝커피를 접수 받는 카운터 역할을 하는 Controller
 * 각 커피별로 생성자를 직접 생성한다.
 * 스프링 IoC 를 사용하지 않음.
 */
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.study.demo._team.di_ioc.beans.Americano;
import com.study.demo._team.di_ioc.beans.Cappuccino;
import com.study.demo._team.di_ioc.beans.Latte;
import com.study.demo._team.di_ioc.service.Smornigservice;


@Controller
public class Ccounter2 {

	/* Call Service */
	Smornigservice Sms;
	
	/* Smornigservice 객체는 어디에서 날라온것인다 
	 * @Autowired 의 생략
	 * DI 는 생성자를 통한 주입을 하도록 가이드되고 있다.
	 * */
	public Ccounter2(Smornigservice sms) {
		super();
		Sms = sms;
	}


	@RequestMapping("/coffee/morning2")
	public String morning_coffee(HttpServletRequest request, Model model) {
		
		 String strCoffee = "";
		 String strMenu= request.getParameter("coffee"); 
		 System.out.println("Ccounter2 =>"+strMenu);
		
		 int menu = Integer.parseInt(strMenu);
		
		 /* Coffee 서비스 */
		 strCoffee = Sms.getMorning(menu);
		 
		 strCoffee = "Ccounter2 | "+ strCoffee; 
		 
		 model.addAttribute("morning_coffee",strCoffee);
		 
		 return "coffee/morning_coffee";		
	}
}

 3. 서비스 - Smornigservice.java

package com.study.demo._team.di_ioc.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.study.demo._team.di_ioc.beans.Americano;
import com.study.demo._team.di_ioc.beans.Cappuccino;
import com.study.demo._team.di_ioc.beans.Latte;

@Service
public class Smornigservice {
	
	Americano ame;
	Latte latte;
	Cappuccino cappu;
	
	/* 생성자 객체 주입 */
	@Autowired
	public Smornigservice(Americano ame, Latte latte, Cappuccino cappu) {
		this.ame = ame;
		this.latte = latte;
		this.cappu = cappu;
	}


	public String getMorning(int menu) {
		
		 String strCoffee = "";
		
		 /* 커피 주문에 따른 메서드 호출 */			
			/* 커피 나왔어요.. */
			if(menu==1) {
				strCoffee = ame.toString();
			}else if(menu==2) {
				strCoffee = latte.toString();
			}else if(menu==3) {
				strCoffee = cappu.toString();
			}
		
		return strCoffee;
			
	}
	
	

}

4. 커피메뉴 - Americano.java , Cappuccino.java , Latte.java

package com.study.demo._team.di_ioc.beans;

import org.springframework.stereotype.Component;

@Component
public class Americano {

	String taste = "깔끔한 맛";
	int price = 4000;
		
	@Override
	public String toString() {
		return "Americano [taste=" + taste + ", price=" + price + "]";
	}
}

-------------------------------------

package com.study.demo._team.di_ioc.beans;

import org.springframework.stereotype.Component;

@Component
public class Cappuccino {
	
	String taste = "우아한 맛";
	int price = 6000;
		
	@Override
	public String toString() {
		return "Cappuccino [taste=" + taste + ", price=" + price + "]";
	}
}

------------------------------------

package com.study.demo._team.di_ioc.beans;

import org.springframework.stereotype.Component;

@Component
public class Latte {
	
	String taste = "달콤한 맛";
	int price = 5000;
		
	@Override
	public String toString() {
		return "Latte [taste=" + taste + ", price=" + price + "]";
	}
}

별도 Spring beans 확인 - Cbeans.java

package com.study.demo._team.di_ioc.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class Cbeans {
	
	@Autowired
	DefaultListableBeanFactory df;

	@RequestMapping("/mybean")
	public String myBean() {
		
		String strBean="";
		int count=0;
		
		for(String str : df.getBeanDefinitionNames()) {
			strBean += df.getBean(str).getClass().getName() + "<br>";  
			count++;
		}
		
		return "Total : "+count+"<p>"+strBean;
	}
}