The Debugging Chronicles : "코드의 미학"
[Spring] 의존성(Dependency) - 생성자 주입 본문
객체생성(new)을 컨테이너로 대신한다 === IoC의 핵심 === Spring 사용하는 이유
"의존성(dependency)"이란?
: 어떤 코드를 수행할 때에 필요한 다른 부분의 코드 내용이 있는가?
"주입(injection)"이란?
: 필요한 다른 부분의 코드 내용을 추가하는 것
"의존성 주입" == DI
Watch를 통해서 IPhone 전원을 켜보자.
근데 위에 코드는 메서드가 실행될 때 마다 new가 된다.
즉, 아이폰은 워치에 대해 의존성을 갖는다.
그래서 다음과 같이 코드를 바꿀 수 있다.
해당 객체를 멤버변수로 두면 관리가 용이하다.
지금은 객체가 없는 상황이다.
메모리를 주어야한다.
그래서 watch에 의존성 주입을 해야한다.
그럼 의존성 주입하는 방법을 알아보자.
의존성 주입하는데는 두가지 방법이 있다.
1. 생성자 주입
- handler mapper
2. Setter 주입
- DTO
1. 생성자 주입
기본 생성자의 멤버변수 메모리를 추가하는 방법은 무조건 new 연산자가 반드시 들어간다
그래서 외부에서, 즉 다른 생성자를 만들어서
메모리를 받아 멤버변수를 셋팅하는 방법을 사용한다.
로그를 살펴볼 필요가 있다. 왜 순서가 이렇게 나왔을까?
원시 타입 넣는 방법
ref 은 객체를 주입하는 것
value는 값을 주입하는 것이다.
다시 한번 해보자
의존성 주입 때문에 코드 순서 대로 로그가 나오는 것이 아니라
8번 라인이 먼저 실행되고 그 다음에 7번 라인이 실행되고
12번 라인이 먼저 실행되고 그 다음에 11번 라인이 실행된다.
12번 라인이 실행 될 때 갤럭시워치만 되고 아이폰워치는 한번 더 실행되지 않는 이유는 싱글톤 때문이다.
Watch.java
package test;
public interface Watch {
void powerOn();
void powerOff();
}
Phone.java
package test;
public interface Phone {
public abstract void powerOn(); // 추상메서드
void powerOff();
}
IPhone.java
package test;
public class IPhone implements Phone {
private Watch watch;
private int num;
public IPhone() {
System.out.println("아이폰 객체 생성 01");
}
public IPhone(Watch watch) {
this.watch=watch;
System.out.println("아이폰 객체 생성 02");
}
public IPhone(Watch watch,int num) {
this.watch=watch;
this.num=num;
System.out.println("아이폰 객체 생성 03");
}
@Override
public void powerOn() {
this.watch.powerOn();
System.out.println("num = "+this.num);
}
@Override
public void powerOff() {
this.watch.powerOff();
}
}
GalaxyWatch.java
package test;
public class GalaxyWatch implements Watch {
public GalaxyWatch() {
System.out.println("갤럭시워치 생성자 호출");
}
@Override
public void powerOn() {
System.out.println("갤럭시워치 ON");
}
@Override
public void powerOff() {
System.out.println("갤럭시워치 OFF");
}
}
GalaxyPhone.java
package test;
public class GalaxyPhone implements Phone {
private Watch watch;
public GalaxyPhone() {
System.out.println("갤럭시 객체 생성 01");
}
public GalaxyPhone(Watch watch) {
this.watch=watch;
System.out.println("갤럭시 객체 생성 02");
}
@Override
public void powerOn() {
this.watch.powerOn();
}
@Override
public void powerOff() {
this.watch.powerOff();
}
}
Client.java
package test;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class Client {
public static void main(String[] args) {
AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
// 컨테이너를 구동시키는 코드
Phone phone = (Phone)factory.getBean("apple");
// Bean == 자바객체 == 객체 == POJO
// 객체를 요청하다.
// == look up
phone.powerOn();
phone.powerOff();
factory.close();
}
}
AppleWatch.java
package test;
public class AppleWatch implements Watch {
public AppleWatch() {
System.out.println("애플워치 생성자 호출");
}
@Override
public void powerOn() {
System.out.println("애플워치로 ON");
}
@Override
public void powerOff() {
System.out.println("애플워치로 OFF");
}
}
applicationContext.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 class="test.IPhone" id="apple">
<constructor-arg ref="aw" />
<constructor-arg value="1234" />
</bean>
<bean class="test.GalaxyPhone" id="samsung">
<constructor-arg ref="gw" />
</bean>
<bean class="test.AppleWatch" id="aw" />
<bean class="test.GalaxyWatch" id="gw" />
</beans>
'Spring' 카테고리의 다른 글
[Spring] 이번주 내용 복습 (0) | 2024.10.04 |
---|---|
[Spring] 의존성(Dependency) - Setter 주입 (2) | 2024.10.02 |
[Spirng] 프레임워크 구조 -2 ( pre-loading / lazy-loading) (0) | 2024.10.01 |
[Spring] 프레임워크 구조 (2) | 2024.10.01 |
[Spring] 시작하기 (0) | 2024.10.01 |