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 |