Java

[Java] 스프링(Spring) DI(Dependency Injection)과 IOC 컨테이너(Container)

구루싸 2020. 9. 23. 17:05
반응형
SMALL

지난 시간에 스프링(Spring) 프로젝트를 생성하기 위한

환경세팅과 간단한 사칙연산 프로그램을 작성해봤습니다

과정이 궁금하시다면 아래의 링크 ↓

2020/09/23 - [Java] - [Java] 스프링(Spring) 환경 세팅하기

 

[Java] 스프링(Spring) 환경 세팅하기

스프링(Spring)을 학습하기에 앞서 알아야할 것은 프레임워크(Frame Work)의 개념일 것입니다 프레임워크는 간단히 말해서 프로그래밍을 단순하게 하여 만들고자 하는 프로그램의 목적에만 집중할 �

yssa.tistory.com

오늘은 스프링의 DI(Dependency Injection)과

IOC 컨테이너(Container)를 살펴보겠습니다

먼저 DI는 의존성 주입이라고 하는데요

위의 그림과 같이 A객체가 B객체, C객체를

가지고 있을 때 A객체는 B,C객체에 의존한다고 합니다

이 때 이 의존성을 주입(DI)하는 방법이 2가지가 있습니다

(그림 참고)

하나는 A객체가 B,C객체를 직접 생성하는 방법이고

다른 하나는 외부에서 객체를 생성해서

A객체에 대입하는 것인데

외부에서 객체를 생성하는 것을

IOC 컨테이너(Container)가 담당합니다

글로 이해가 안되더라도

일단 지난 번 생성했던 사칙연산

프로그램을 수정해보겠습니다

1. Calculator.java

package com.example.demo;

public class Calculator {
	public void addition(int firstNum, int secondNum) {
		System.out.println("addition()");
		int result = firstNum + secondNum;
		System.out.println(firstNum + " + " + secondNum + " = " + result);
	}
	
	public void subtraction(int firstNum, int secondNum) {
		System.out.println("subtraction()");
		int result = firstNum - secondNum;
		System.out.println(firstNum + " - " + secondNum + " = " + result);
	}
	
	public void multiplication(int firstNum, int secondNum) {
		System.out.println("multiplication()");
		int result = firstNum * secondNum;
		System.out.println(firstNum + " * " + secondNum + " = " + result);
	}
	
	public void division(int firstNum, int secondNum) {
		System.out.println("division()");
		if ( secondNum == 0 ) {
			System.out.println("It cannot be divided by zero.");
		}
		int result = firstNum / secondNum;
		System.out.println(firstNum + " / " + secondNum + " = " + result);
	}
}

2. MyCalculator.java

package com.example.demo;

public class MyCalculator {

	Calculator calculator;
	private int firstNum;
	private int secondNum;
	
	public MyCalculator() {

	}

	public void add() {
		calculator.addition(firstNum, secondNum);
	}
	
	public void sub() {
		calculator.subtraction(firstNum, secondNum);
	}
	
	public void mul() {
		calculator.multiplication(firstNum, secondNum);
	}
	
	public void div() {
		calculator.division(firstNum, secondNum);
	}
	
	public void setCalculator(Calculator calculator) {
		this.calculator = calculator;
	}
	
	public void setFirstNum(int firstNum) {
		this.firstNum = firstNum;
	}
	
	public void setSecondNum(int secondNum) {
		this.secondNum = secondNum;
	}
}

3. MainClass.java

package com.example.demo;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class MainClass {
	public static void main(String[] args) {
		String configLocation = "classpath:applicationCTX.xml";
		AbstractApplicationContext ctx = new GenericXmlApplicationContext(configLocation);
		MyCalculator myCalculator = ctx.getBean("myCalculator", MyCalculator.class);
		
		myCalculator.add();
		myCalculator.sub();
		myCalculator.mul();
		myCalculator.div();
	}
}

4. applicationCTX.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="calculator" class="com.example.demo.Calculator" />
	
	<bean id="myCalculator" class="com.example.demo.MyCalculator">
		<property name="calculator">
			<ref bean="calculator"/>
		</property>
		<property name="firstNum" value="10" />
		<property name="secondNum" value="2"></property>
	</bean>
</beans>

applicationCTX.xml 파일은

src/main/resources 경로에 살짝 넣어주세요^^

위의 코드를 실행시키면

지난 번과 동일한 결과가 나올 것입니다

DI를 설정하는 방법은

위의 방식처럼 xml파일을 이용하는 방법과

java를 이용한 방법이 있습니다

1. xml을 이용한 방식

1-1. applicationCTX.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"
	xmlns:c="http://www.springframework.org/schema/c"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<bean id="student" class="com.example.demo.Student">
		<constructor-arg value="GuruSa" />
		<constructor-arg value="8" />
		<constructor-arg>
			<list>
				<value>농구</value>
				<value>축구</value>
			</list>
		</constructor-arg>
		
		<property name="height">
			<value>187</value>
		</property>
		
		<property name="weight" value="84" />
	</bean>
	
	<bean id="family" class="com.example.demo.Family" c:papaName="papaSa" c:mamiName="mamiSa" p:brotherName="brotherSa">
		<property name="sisterName" value="sisterSa" />
	</bean>
	
</beans>

1-2. Family.java

package com.example.demo;

public class Family {

	String papaName;
	String mamiName;
	String sisterName;
	String brotherName;
	
	public Family(String papaName, String mamiName) {
		this.papaName = papaName;
		this.mamiName = mamiName;
	}

	public String getPapaName() {
		return papaName;
	}

	public void setPapaName(String papaName) {
		this.papaName = papaName;
	}

	public String getMamiName() {
		return mamiName;
	}

	public void setMamiName(String mamiName) {
		this.mamiName = mamiName;
	}

	public String getSisterName() {
		return sisterName;
	}

	public void setSisterName(String sisterName) {
		this.sisterName = sisterName;
	}

	public String getBrotherName() {
		return brotherName;
	}

	public void setBrotherName(String brotherName) {
		this.brotherName = brotherName;
	}
	
}

1-3. Student.java

package com.example.demo;

import java.util.ArrayList;

public class Student {

	private String name;
	private int age;
	private ArrayList<String> hobbys;
	private double height;
	private double weight;
	
	public Student(String name, int age, ArrayList<String> hobbys) {
		this.name = name;
		this.age = age;
		this.hobbys = hobbys;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public void setAge(int age) {
		this.age = age;
	}

	public void setHobbys(ArrayList<String> hobbys) {
		this.hobbys = hobbys;
	}
	
	public void setHeight(double height) {
		this.height = height;
	}
	
	public void setWeight(double weight) {
		this.weight = weight;
	}
	
	public String getName() {
		return name;
	}
	
	public int getAge() {
		return age;
	}
	
	public ArrayList<String> getHobbys() {
		return hobbys;
	}
	
	public double getHeight() {
		return height;
	}
	
	public double getWeight() {
		return weight;
	}
	
}

1-4. MainClass.java

package com.example.demo;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;

public class MainClass {

	public static void main(String[] args) {
		
		String configLocation = "classpath:applicationCTX.xml";
		AbstractApplicationContext ctx = new GenericXmlApplicationContext(configLocation);
		
		Student student = ctx.getBean("student", Student.class);
		System.out.println(student.getName());
		System.out.println(student.getHobbys());
		
		Family family = ctx.getBean("family", Family.class);
		System.out.println(family.getPapaName());
		System.out.println(family.getMamiName());
		System.out.println(family.getSisterName());
		System.out.println(family.getBrotherName());
		
		ctx.close();
		
	}
	
}

2. java를 이용한 방식

2-1. ApplicationConfig.java

package com.example.demo;

import java.util.ArrayList;

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

@Configuration
public class ApplicationConfig {

	@Bean
	public Student student1(){
		
		ArrayList<String> hobbys = new ArrayList<String>();
		hobbys.add("축구");
		hobbys.add("농구");
		
		Student student = new Student("GuruSa", 20, hobbys);
		student.setHeight(180);
		student.setWeight(80);
		
		return student;
	}
	
	@Bean
	public Student student2(){
		
		ArrayList<String> hobbys = new ArrayList<String>();
		hobbys.add("독서");
		hobbys.add("음악감상");
		
		Student student = new Student("BuruSa", 18, hobbys);
		student.setHeight(170);
		student.setWeight(55);
		
		return student;
	}
	
}

2-2. Student.java

package com.example.demo;

import java.util.ArrayList;

public class Student {

	private String name;
	private int age;
	private ArrayList<String> hobbys;
	private double height;
	private double weight;
	
	public Student(String name, int age, ArrayList<String> hobbys) {
		this.name = name;
		this.age = age;
		this.hobbys = hobbys;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public void setAge(int age) {
		this.age = age;
	}

	public void setHobbys(ArrayList<String> hobbys) {
		this.hobbys = hobbys;
	}
	
	public void setHeight(double height) {
		this.height = height;
	}
	
	public void setWeight(double weight) {
		this.weight = weight;
	}
	
	public String getName() {
		return name;
	}
	
	public int getAge() {
		return age;
	}
	
	public ArrayList<String> getHobbys() {
		return hobbys;
	}
	
	public double getHeight() {
		return height;
	}
	
	public double getWeight() {
		return weight;
	}
	
}

2-3. MainClass.java

package com.example.demo;

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MainClass {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ApplicationConfig.class);
		
		Student student1 = ctx.getBean("student1", Student.class);
		System.out.println("이름 : " + student1.getName());
		System.out.println("나이 : " + student1.getAge());
		System.out.println("취미 : " + student1.getHobbys());
		System.out.println("신장 : " + student1.getHeight());
		System.out.println("몸무게 : " + student1.getWeight());
		
		Student student2 = ctx.getBean("student2", Student.class);
		System.out.println("이름 : " + student2.getName());
		System.out.println("나이 : " + student2.getAge());
		System.out.println("취미 : " + student2.getHobbys());
		System.out.println("신장 : " + student2.getHeight());
		System.out.println("몸무게 : " + student2.getWeight());
		
		ctx.close();
	}
	
}

위의 코드를 실행해보시면서

의미를 파악해보시면 금방 아실 수 있을 것 같고

아직은 DI사용에 따른 장점을

몸으로 느끼기에는 부족하겠지만

DI사용의 장점을 말하자면

Java 파일의 수정 없이 스프링 설정 파일만

수정하여 부품들을 생성하고 조립할 수 있다는 것입니다

차차 진도를 나가다보면

저절로 혹은 스트레스 받으면서

알 수 있기 때문에 더 이상의 설명은 생략할께요!

아 참고로 혹시 경로상에 한글이 있어서 에러가 뜰 수 있는데요

그럴 때는 pom.xml 파일에 아래의 코드를 추가해주세요

<!-- 한글 문제 해결 -->
<dependency>
  <groupId>xerces</groupId>
  <artifactId>xercesImpl</artifactId>
  <version>2.9.1</version>
</dependency>

이것으로 오늘의 학습을 마치겠습니다-_-

반응형
LIST