프로필사진
DI(1) - DI란, XML에서 bean생성&주입

2019. 11. 13. 10:05🔴 Spring

300x250

DI = 의존기능

(Dependency Injection)
#Framework에 의해 객체의 의존성이 주입되는 설계 패턴
#스프링 IOC(제어의 역전 - 프로그램 제어권을 framework가 가져감)컨테이너 핵심 개념 중 하나

  • 스프링 컨테이너 → Bean 객체 저장, 각 객체간의 의존관계 관리해줌
  • 의존성 주입 : 객체 자신이 아닌 외부(조립기)에 의해 설정됨
  • 컨테이너 역할: 의존관계에 있는 다른 객체 B객체를 직접 생성 → A객체로 주입(설정)
    Spring → 조립기(Assembler) 기능을 보유한 컨테이너가 자동으로 주입함
    Bean(클래스 / 객체)의 생성과 관계 설정, 사용, 제거 등의 기능을 담당
    메소드 제공 → getBean()
  • 범용적으로 사용할 수 있는 조립기 제공 설정파일 → .xml : 객체정보 설정 / 의존 주입

즉, 컨테이너가 bean객체를 생성하고, 종속성 주입을 수행함!

 


DI의 장점 (=객체 간의 의존관계를 외부의 조립기가 관리하면 뭐가 좋을까?) :

  • 객체까리의 불필요한 의존 관계를 없애거나 줄임
    b/c A객체가 변경될 때 B객체에 영향을 주지 않도록 하기 때문
    (외부에서 미리 객체를 만들어놓고 필요할 때 주입!!)
  • 단위테스트 수월
  • 각 객체를 빈으로 관리
  • 설정파일 & 어노테이션을 사용해서 객체간의 의존관계를 설정

BeanFactory 인터페이스 :
Bean객체를 관리, 의존관계 설정해주는 컨테이너 XML과 같은 외부 설정 파일의 내용을 기반으로 객체 생성 → Spring 컨테이너 생성

XmlBeanFactory클래스 → 외부 자원으로부터 설정정보를 읽어와 Bean객체 생성


★ DI 설정

 

XML에서 Bean 생성, 주입

* static메소드 이용해서 객체를 구해야하는 경우 / 싱글톤 패턴이 적용된 클래스인 경우 :

<bean id=“memberDao" class=“dao.MemberDao“ factory-method=“getinstance” />
자바코드에서 싱글톤 코드를 작성하지 않더라도 싱글톤 처리가 됨, bean에서 설정!!!

1) 생성자 주입 방식

service 클래스 내에 생성자 없음 → <constructor-arg ref=" " />

2) 프로퍼티 주입 방식 (=setter메소드 호출)

<property name = " " ref= " " />

<appCtx1.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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
	
	<!-- MemberDao 객체를 bean으로 등록, 식별자는 memberDao -->
	<bean id="memberDao" class="member.MemberDao"/>
	
	<!-- @@ 생성자 주입방식 @@ -->
	<!-- MemberRegisterService 안에 생성자가 없으므로(bean생성 조건) 설정해줘야함 -->
	<!-- 태그 사이에서 자식 태그로 설정하기 -->
	<!-- <bean id="registService" class="member.MemberRegisterService">
		<constructor-arg>
			<ref bean="memberDao"/>
		</constructor-arg>
	</bean> -->
	
	<!-- @@ 프러퍼티 주입방식 @@ -->
	<!-- 주의 : bean생성까지는 가능, 오류표시 안해주므로 property썼는지 확인해야함 -->
	<bean id="registService" class="member.MemberRegisterService">
		<property name="memberDao">

			<!-- <ref bean="memberDao"/> -->

			<!-- 의존관계 설정 : 임의 빈 객체 전달 = MemberRegisterService생성할때만 한번 씀 -->
			<!-- 새로운 객체 MemberDao를 생성해서 넣는 것, 위에 있는 memberDao id값으로 쓰지 않음 -->
			<bean class="member.MemberDao"/>

		</property>
	</bean>
	
	<!-- 줄여쓰기 -->
	<bean 
	id="changePwService" class="member.ChangePasswordService" p:memberDao-ref="memberDao">
		<!-- 태그 안에서 ref속성으로 설정하기 -->
		<!-- 만약 참조가 아니라면 ref대신 value사용 -->
		<!-- <property name="memberDao" ref="memberDao"/> -->
		<!-- <constructor-arg ref="memberDao"/> -->
	</bean>

</beans>

<MemberRegisterService.java>

package member;
// 회원가입 처리 
import java.util.Date;

import javax.annotation.Resource;

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

@Service
public class MemberRegisterService {
	
	private MemberDao memberDao;
	
	 // setter 방식 (property사용)
		public void setMemberDao(MemberDao memberDao) {
		this.memberDao = memberDao;
	}

	/* 생성자 생략함 (constructor사용)
	 * public MemberRegisterService(MemberDao memberDao) { 
	 * this.memberDao = memberDao; }
	 */

	public void regist(RegisterRequest request) throws AlreadyExistingMemberException {
		
		// 사용자가 입력한 email -> 기존 저장된 데이터에 있는지 찾기
		Member member = memberDao.selectByEmail(request.getEmail());

		if (member != null) {
			throw new AlreadyExistingMemberException();
		}
		
		// 겹치는 데이터가 없으면 회원가입 실행
		Member newMember = new Member(request.getEmail(), request.getPassword(), request.getName(), new Date());
		
		// + id도 같이 생성
		memberDao.insert(newMember);

	}

}

임의 빈 객체 전달 (식별자를 갖지 않는 빈 객체 생성, 전달)

→ <constructor-arg>나 <property>에 <bean>중첩해서 사용!

<bean id="registService" class="member.MemberRegisterService">
		<property name="memberDao">
			<!-- 의존관계 설정 : 임의 빈 객체 전달 = MemberRegisterService생성할때만 한번 씀 -->
			<!-- 새로운 객체 MemberDao를 생성해서 넣는 것, 위에 있는 memberDao id값으로 쓰지 않음 -->
			<bean class="member.MemberDao"/>
			id값이 없음 -> 이후에 쓰지 않을 때 이렇게 사용!!
		</property>
	</bean>

2개 이상의 설정파일 이용

<import resource= " "> : 외부파일 설정

의존관계 자동 설정 : 의존하는 빈 객체의 타입이나 이름으로 의존객체 자동설정

  • byName
  • byType
  • constructor

⇒ 하지만 보통 annotation방식

<?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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
	
	<!-- MemberDao 객체를 bean으로 등록, 식별자는 memberDao -->
	<bean id="memberDao" class="member.MemberDao"/>
	
	<!-- 의존관계 자동설정 -->
	<!-- byName = 프로퍼티의 이름과 같은 이름을 갖는 빈 객체를 설정 -->
	<bean id="registService" class="member.MemberRegisterService" autowire="byName">
		
	</bean>
	
	<!-- byType = 프로퍼티의 타입과 같은 타입을 갖는 빈 객체를 설정 -->
	<bean id="changePwService" class="member.ChangePasswordService" autowire="byType">
		
	</bean>

</beans>
300x250

'🔴 Spring' 카테고리의 다른 글

DispatcherServlet이란?  (0) 2019.11.14
AOP - AOP란? AOP vs OOP  (1) 2019.11.13
SpringMVC에서의 Annotation, 간단 정리!  (0) 2019.11.13
DI(3) - XML없이 자바 코드 기반 설정  (0) 2019.11.13
DI(2) - Annotation사용하기  (0) 2019.11.13