Spring복습 DI에 대해서..

충찌·2022년 1월 8일
0

Spring-remind

목록 보기
1/4
post-thumbnail

Spring 프레임워크의 대표적인 4가지

  1. DI
  2. AOP
  3. Spring MVC
  4. ORM
![](https://velog.velcdn.com/images%2Fthgus0426%2Fpost%2Ff0c65452-de59-4259-a9b8-79aefea50c2e%2Fimage.jpeg)

IOC(Inversion of Control)
: 기존의 프로그래밍에서 개발자가 관리하던 객체의 라이프 사이클(생성, 제어, 소멸 등)을 컨테이너에게 제어권을 위임하는 프로그래밍 기법
: 의존성들을 외부에 정의하고 컨테이너에 의해 공급받음

IOC의 장점

  • 유지보수 용이성
  • 용이한 환경설정
  • 재사용 용이성
  • 테스트 용이성

IOC의 구현 방법

  1. DL(Dependency Lookup)
    : 의존성 검색
    : 저장소에 저장되어 있는 빈(Bean)에 접근하기 위하여 개발자들이 컨테이너에서 제공하는 API를 이용하여 사용하고자하는 빈을 Lookup하는 것
  2. DI(Dependency Injection)
    : 의존성 주입
    : 각 계층, 클래스 사이에 필요로 하는 의존 관계를 컨테이너가 자동으로 연결
    : DL사용 시 컨테이너 종속성이 증가하는데 이를 줄이기 위해 DI 사용

DI의 종류

  1. Setter Injection
    : Spring 프레임워크의 빈 설정 파일에서 property 사용
  2. Constructor Injection
    : Spring 프레임워크의 빈 설정 파일에서 Constructor-arg사용
  3. Method Injection

DI 사용 예시(xml, setter injection)

<BMICalculator.java>
package DI02;

public class BMICalculator {
	private double lowWeight;
	private double normal;
	private double overWeight;
	private double obesity;
	
	public void bmicalculation(double weight, double height) {
		double h = height * 0.01;
		double result = weight / (h*h);
		
		System.out.println("BMI 지수: "+(int)result);
		
		if(result > obesity) {
			System.out.println("비만.");
		}else if(result > overWeight) {
			System.out.println("과체중.");
		}else if(result > normal) {
			System.out.println("정상.");
		}else {
			System.out.println("저체중.");
		}
	}

	public void setLowWeight(double lowWeight) {
		this.lowWeight = lowWeight;
	}

	public void setNormal(double normal) {
		this.normal = normal;
	}

	public void setOverWeight(double overWeight) {
		this.overWeight = overWeight;
	}

	public void setObesity(double obesity) {
		this.obesity = obesity;
	}
}


<MyInfo.java>
package DI02;

import java.util.ArrayList;

public class MyInfo {
	private String name;
	private double height;
	private double weight;
	private ArrayList<String> hobbies;
	private BMICalculator bmiCalculator;
	
	public void bmiCalculation() {
		bmiCalculator.bmicalculation(weight, height);
	}
	
	public void getInfo() {
		System.out.println("이름: "+name);
		System.out.println("키: "+height);
		System.out.println("몸무게: "+weight);
		System.out.println("취미: "+hobbies);
		bmiCalculation();
	}

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

	public void setHeight(double height) {
		this.height = height;
	}

	public void setWeight(double weight) {
		this.weight = weight;
	}

	public void setHobbies(ArrayList<String> hobbies) {
		this.hobbies = hobbies;
	}

	public void setBmiCalculator(BMICalculator bmiCalculator) {
		this.bmiCalculator = bmiCalculator;
	}
}


<MainClass.java>
package DI02;

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

public class MainClass {

	public static void main(String[] args) {
		String configLocation = "classpath:applicationCTX2.xml";
		AbstractApplicationContext ctx = new GenericXmlApplicationContext(configLocation);
		MyInfo myInfo = ctx.getBean("myInfo", MyInfo.class);
		myInfo.getInfo();
		ctx.close();
	}

}


<applicationCTX2.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="bmiCalculator" class="DI02.BMICalculator">
	  <property name="lowWeight" value="18.5"/>
   	  <property name="normal" value="23"/>
    	  <property name="overWeight" value="25"/>
   	  <property name="obesity" value="30"/>
    </bean>
    
    <bean id="myInfo" class="DI02.MyInfo">
    	<property name=" value="김춘추"/>
        <property name="height" value="170"/>
        <property name="weight" value="72"/>
        <property name="hobbies">
           <list>
           	<value>말타기</value>
                <value>활쏘기</value>
           </list>
        </property>
        <property name="bmiCalculator>
          <ref bean="bmiCalculator"/>
        </property>
    </bean>

</beans>





<결과>
김춘추
키: 170.0
몸무게: 72.0
취미: [말타기, 활쏘기]
BMI 지수: 24
정상

DI 사용 예시(xml, constructor injection)

<Student.java>
package DI03;

public class Student {
	private String name;
	private int age;
	private String gradeNum;
	private String classNum;
	
	public Student(String name, int age, String gradeNum, String classNum) {
		super();
		this.name = name;
		this.age = age;
		this.gradeNum = gradeNum;
		this.classNum = classNum;
	}

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

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

	public String getGradeNum() {
		return gradeNum;
	}

	public void setGradeNum(String gradeNum) {
		this.gradeNum = gradeNum;
	}

	public String getClassNum() {
		return classNum;
	}

	public void setClassNum(String classNum) {
		this.classNum = classNum;
	}
	
	
}


<StudentInfo.java>
package DI03;

public class StudentInfo {
	private Student student;

	public StudentInfo(Student student) {
		this.student = student;
	}

	public void getStudentInfo() {
		if(student!=null) {
			System.out.println("이름: "+student.getName());
			System.out.println("나이: "+student.getAge());
			System.out.println("학년: "+student.getGradeNum());
			System.out.println("반 : "+student.getClassNum());
			System.out.println("==================");
		}
	}

	public Student getStudent() {
		return student;
	}

	public void setStudent(Student student) {
		this.student = student;
	}
	
}



<MainClass.java>
package DI03;

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

public class MainClass {

	public static void main(String[] args) {
		String configLocation = "classpath:applicationCTX3.xml";
		AbstractApplicationContext ctx = new GenericXmlApplicationContext(configLocation);
		
		StudentInfo studentInfo = ctx.getBean("studentInfo", StudentInfo.class);
		studentInfo.getStudentInfo();
		
		Student student2 = ctx.getBean("student2", Student.class);
		studentInfo.setStudent(student2);
		studentInfo.getStudentInfo();
		System.out.println("student2.getAge()-->"+student2.getAge());
		System.out.println(student2.getAge()+5);
		ctx.close();
		
		Student student3 = new Student("김유신", 30, "3학년", "11번");
		System.out.println("student3.getAge()-->"+student3.getAge());
	}

}



<applicationCTX3.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="student1" class="DI03.Student">
		<constructor-arg value="연개소문"/>
		<constructor-arg value="50"/>
		<constructor-arg value="4학년"/>
		<constructor-arg value="25번"/>
	</bean>
	
	<bean id="student2" class="DI03.Student">
		<constructor-arg value="양만춘"/>
		<constructor-arg value="38"/>	
		<constructor-arg value="3학년"/>	
		<constructor-arg value="11번"/>	
	</bean>
	
	<bean id="studentInfo" class="DI03.StudentInfo">
		<constructor-arg>
			<ref bean="student1"/>
		</constructor-arg>
	</bean>
</beans>



<결과>
이름: 연아들
나이: 50
학년: 4학년
반 : 25번
==================
이름: 양만춘
나이: 38
학년: 3학년
반 : 11번
==================
student2.getAge()-->38
43
student3.getAge()-->30

Map클래스인 경우 DI예시(xml, setter injection)

<CollectionBean.java>
package DI04;

import java.util.Map;

public class CollectionBean {
	private Map<String, String> addressList;

	public Map<String, String> getAddressList() {
		return addressList;
	}

	public void setAddressList(Map<String, String> addressList) {
		this.addressList = addressList;
	}
	
	
}



<MainClass.java>
package DI04;

import java.util.Map;

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

public class MainClass {

	public static void main(String[] args) {
		String configLocation = "classpath:applicationCTX4.xml";
		AbstractApplicationContext ac = new GenericXmlApplicationContext(configLocation);
		
		CollectionBean collectionBean = ac.getBean("collectionBean", CollectionBean.class);
		Map<String, String> addressList = (Map<String,String>)collectionBean.getAddressList();
		System.out.println("홍길동 주소 :"+addressList.get("홍길동"));
		System.out.println("중앙 주소 :"+addressList.get("중앙"));
	}

}


<applicationCTX4.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="collectionBean" class="DI04.CollectionBean">
  <property name="addressList">
    <map>
	<entry>
	  <key><value>홍길동</value></key><value>율도국</value>
	</entry>
	<entry>
	  <key><value>중앙</value></key><value>강남</value>
	</entry>
   </map>
 </property>
</bean>

</beans>



<결과>
홍길동 주소 :율도국
중앙 주소 :강남

DI예시(Annotation, setter injection, constructor injection)

<Student.java>
package DI07;

import java.util.ArrayList;

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

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

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

	public ArrayList<String> getHobbies() {
		return hobbies;
	}

	public void setHobbies(ArrayList<String> hobbies) {
		this.hobbies = hobbies;
	}

	public double getWeight() {
		return weight;
	}

	public void setWeight(double weight) {
		this.weight = weight;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}
	
	
}



<ApplicationConfig.java>
package DI07;

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> hobbies = new ArrayList<String>();
		hobbies.add("팝뮤직");
		hobbies.add("피아노");
		
		Student student = new Student("안예은", 27, hobbies);
		student.setHeight(160);
		student.setWeight(50);
		
		return student;
	}
	@Bean
	public Student student2() {
		ArrayList<String> hobbies = new ArrayList<String>();
		hobbies.add("뮤지컬");
		hobbies.add("음악감상");
		
		Student student = new Student("김준수", 35, hobbies);
		student.setHeight(178);
		student.setWeight(70);
		
		return student;
	}
}


<MainClass.java>
package DI07;

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.getHobbies());
		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.getHobbies());
		System.out.println("신장: "+student2.getHeight());
		System.out.println("몸무게: "+student2.getWeight());
	}

}



<결과>
이름: 안예은
나이: 27
취미: [팝뮤직, 피아노]
신장: 160.0
몸무게: 50.0
이름: 김준수
나이: 35
취미: [뮤지컬, 음악감상]
신장: 178.0
몸무게: 70.0

DI 예시(xml+Annotation 혼합)

<Student>
package DI08;

import java.util.ArrayList;

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

	public String getName() {
		return name;
	}

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

	public int getAge() {
		return age;
	}

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

	public ArrayList<String> getHobbies() {
		return hobbies;
	}

	public void setHobbies(ArrayList<String> hobbies) {
		this.hobbies = hobbies;
	}

	public double getWeight() {
		return weight;
	}

	public void setWeight(double weight) {
		this.weight = weight;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}
	
	
}


<ApplicationConfig.java>
package DI08;

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> hobbies = new ArrayList<String>();
		hobbies.add("수영");
		hobbies.add("물내리기");
		
		Student student = new Student("을지문덕", 55, hobbies);
		student.setHeight(170);
		student.setWeight(70);
				
		return student;
	}
}


<MainClass.java>
package DI08;

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

import DI08.Student;

public class MainClass {
	public static void main(String[] args) {
		AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationCTX8.xml");
		
		Student student1 = ctx.getBean("student1",Student.class);
		System.out.println("이름: "+student1.getName());
		System.out.println("나이: "+student1.getAge());
		System.out.println("취미: "+student1.getHobbies());
		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.getHobbies());
		System.out.println("신장: "+student2.getHeight());
		System.out.println("몸무게: "+student2.getWeight());
		ctx.close();
	}
}



<applicationCTX8.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: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-4.1.xsd">

    //context로 Annotation과 xml 환경설정 연결
	<context:annotation-config></context:annotation-config>
	<bean class="DI08.ApplicationConfig"></bean>
	
	<bean id="student2" class="DI08.Student">
		<constructor-arg value="양만춘"/>
		<constructor-arg value="30"/>
		<constructor-arg>
			<list>
				<value>활쏘기</value>
				<value>안시성</value>
			</list>
		</constructor-arg>
		<property name="height" value="175"/>
		<property name="weight" value="70"/>
	</bean>

</beans>


<결과>
이름: 을지문덕
나이: 55
취미: [수영, 물내리기]
신장: 170.0
몸무게: 70.0
이름: 양만춘
나이: 30
취미: [활쏘기, 안시성]
신장: 175.0
몸무게: 70.0

정리

xml과 Annotation 각각의 특징

xml은 AbstractApplicationContext ctx = new GenericXmlApplicationContext("classpath:");를 사용하고,
Annotation은 @Configuration과 @Bean을 설정해 준 후
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(클래스명.class);를 사용하여 연결해준다.

xml과 annotation을 혼합 사용 시에는 xml파일에서 <context:annotaion-config/>를 작성해 annotation연결을 수행한다.



DI 종류 중 setter와 constructor 각각의 장점

--Setter Injection

  • 생성자 Parameter목록이 길어지는 것 방지
  • 생성자의 수가 많아지는 것 방지
  • Circular dependencies 방지

--Constructor Injection

  • 강한 의존성 계약 강제
  • Setter 메소드 과다 사용 억제
  • 불필요한 Setter 메소드를 제거함으로써 실수로 속성값을 변경하는 일을 사전에 방지
profile
벨로그? 난 켈로그

0개의 댓글