본문 바로가기
Programming/Spring

[Spring] Spring DI (Chapter 3) - 1

* 이 포스팅은예제 코드를 생략한다. 

* 예제 코드는 https://github.com/seoeunhyo/Spring

 

seoeunhyo/Spring

스프링 프로그래밍 개인 공부 . Contribute to seoeunhyo/Spring development by creating an account on GitHub.

github.com

* 최범균의 스프링5 프로그래밍 도서를 참고했다. 

 


 

1. 의존이란? 

DI는 Dependency Injection의 약자로, 의존 주입이라고 번역한다. 여기서 말하는 의존은, 객체 간의 의존을 의미한다. 

예를 들어, 회원가입을 생각할때 존재하는지 여부를 확인할 때 Dao의 클래스의 메서드를 사용한다는 점이다. 이를 객체(클래스)간 의존한다고 표현할 수 있다. 

의존하는 객체를 직접 생성하는 대신, 의존 객체를 전달받는 방식을 사용한다. 

예를들어, public MemberregisterService(MemberDao memberDao){this.memberDao = memberDao;}와 같이 직접 객체를 생성하지 않고 생성자를 통해 의존 객체를 전달받는다. 

 

 

2. 조립기

조립기는 객체를 생성하고 의존 객체를 주입하는 기능을 제공한다. 또한 특정 개체가 필요한 곳에 객체를 제공한다. 

예를 들어 Assembler 클래스의 getMemberRegisterService() 메서드는 MemberRegisterService 객체가 필요한 곳에 사용된다. Main 메서드에서 의존 대상 객체를 생성하고 주입하는 방법이 나쁘지는 않다. 이 방법보다 더 나은 방법이 개체를 생성하고 의존 객체를 주입하주는 클래스를 따로 작성하는 것이다. 

(객체를 생성하고 주입하는 부분을 따로 작성하는게 관리 차원에서 효율이 좋다고 한다.)

public class Assembler {
	private MemberDao memberDao;
	private MemberRegisterService regSvc;
	private ChangePasswordService pwdSvc;
	
	public Assembler() {
		memberDao = new MemberDao();
		regSvc = new MemberRegisterService(memberDao);
		pwdSvc = new ChangePasswordService();
		pwdSvc.setMemberDao(memberDao);
	}
	public MemberDao getMemberDao() {
		return memberDao;
	}
	
	public MemberRegisterService getMemberRegisterService() {
		return regSvc;
	}
	public ChangePasswordService getChangePasswordService() {
		return pwdSvc;
	}
}

 

assmebler는 자신이 생성하고 조립한 객체를 리턴하는 메서드를 제공한다. 위 코드처럼 사용하는 것은 전형적인 assembler 사용법이다.

 

3. 스프링은? 

스프링은 앞서 구현한 조립기와 유사한 기능을 제공한다. 즉 스프링은 Assembler 클래스의 생성자 코드처럼 필요한 객체를 생성하고 생성한 객체에 의존을 주입한다. 스프링은 범용 조립기이다. 

 

package config;

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

import spring.ChangePasswordService;
import spring.MemberDao;
import spring.MemberRegisterService;


@Configuration
public class AppCtx {
	
	@Bean
	public MemberDao memberDao() {
		return new MemberDao();
	}
	
	@Bean
	public MemberRegisterService memberRegSvc() {
		return new MemberRegisterService(memberDao());
	}
	
	@Bean
	public ChangePasswordService changePwdSvc() {
		ChangePasswordService pwdSvc = new ChangePasswordService();
		pwdSvc.setMemberDao(memberDao());
		return pwdSvc;
	}
	
	
}

 

@Configuration 애노테이션은 스프링 설정 클래스를 의미한다. 이 애노테이션을 붙여야 스프링 설정 클래스로 사용할 수 있다. 

@Bean은 해당 메서드가 생성한 객체를 스프링 빈이라고 설정한다. 위 코드의 경우 세 개의 메서드에 Bean이 존재하는데, 각각의 메서드마다 한개의 빈 객체를 생성한다. 이 때 메서드 이름을 빈 객체의 이름으로 사용하는데, memberDao() 메서드를 이용해서 생성한 빈 객체는 "memberDao"라는 이름으로 스프링에 등록된다. 

 

이를 기반으로 다시 main을 작성하면, 아래 2번째 줄과 같이 바꿀 수 있다. 

즉, assembler 역할을 spring이 대신해주는 것이다.

MemberRegisterService regSvc = assembler.getMemberRegisterService();

 

MemberRegisterService regSvc = ctx.getBean("memberRegSvc", MemberRegisterService.class);

AppCtx.config에 MemberRegisterService 메서드를 "memberRegSvc"라는 이름으로 Bean 등록을 해놨다. 

스프링 컨테이너는 Assembler와 동일하게 객체를 생성하고 의존 객체를 주입한다. 

 

 

4.1 DI 방식 2: 세터 메서드 방식

 

- 일반적인 세터 메서드 자바빈 규칙

1. 메서드 이름이 set으로 시작한다.

2. set 뒤에 첫 글자는 대문자로 시작한다.

3. 파라미터가 1개이다.

4. 리턴 타입이 void다.