[Spring] DI 개념과 스프링의 DI 지원, 스프링 빈 의존관계 설정

JeongEun Kim·2023년 4월 25일
1

Spring

목록 보기
3/8

Spring DI 용어 정리

Bean(빈)

  • 스프링이 IoC 방식으로 관리하는 오브젝트
  • 스프링이 직접 생성과 제어를 담당하는 오브젝트만을 Bean이라 부름

BeanFactory(빈 팩토리)

  • 스프링이 IoC를 담당하는 핵심 컨테이너
  • Bean을 등록, 생성, 조회, 반환하는 기능 담당
  • BeanFactory를 확장한 ApplicationContext를 이용함

ApplicationContext(애플리케이션 컨텍스트)

  • BeanFactory를 확장한 IoC 컨테이너
  • Bean을 등록하고 관리하는 기본 기능은 BeanFactory와 동일
  • 스프링이 제공하는 각종 부가 서비스 추가 제공
  • BeanFactory라 부를 때는 주로 빈의 생성과 제어의 관점, ApplicationContext라 할 때는 스프링이 제공하는 애플리케이션 지원 기능을 모두 포함해서 이야기하는 것

Configuration Metadata(설정정보/설정 메타정보)

  • 스프링의 설정정보란, ApplicationContext 또는 BeanFactory가 IoC를 적용하기 위해 사용하는 메타정보를 말함. 이는 구성정보 내지는 형상정보를 의미함.
  • 설정정보는 IoC 컨테이너에 의해 관리되는 Bean 객체를 생성하고 구성할 때 사용됨.

Spring Framework

  • 스프링 프레임워크는 IoC 컨테이너, ApplicationContext를 포함해 스프링이 제공하는 모든 기능을 통틀어 말할 때 주로 사용됨



Dependency Injection(의존성 주입)

Dependency Injection이란?

객체 간의 의존관계를 자신이 아닌 외부의 조립기가 수행한다. 제어의 역행(Inversion of Control)이란 의미로 사용된다. DI를 통해 시스템에 있는 각 객체를 조정하는 외부 개체가 객체들에게 생성시 의존관계가 주어진다.
느슨한 결합(loose coupling)으로 객체를 변화시키며, 느슨한 결합시에 객체는 인터페이스에 의한 의존 관계만을 알고 있어 구현 클래스에 대한 차이를 모르는 채 서로 다른 구현으로 대체가 가능하다.

스프링의 DI 지원

스프링 컨테이너가 DI 조립기를 제공한다.

스프링 설정 파일을 통해 객체 간의 의존관계를 설정할 수 있으며, 스프링 컨테이너가 제공하는 API를 이용해 객체를 사용할 수 있다.


빈 생성범위

싱글톤 빈

  • 스프링 빈은 기본적으로 싱글톤 으로 만들어짐
  • 즉, 컨테이너가 제공하는 모든 빈의 인스턴스는 항상 동일
  • 컨테이너가 항상 새로운 인스턴스를 반환하게 만들고 싶을 경우 scope를 prototype으로 설정해야함

빈의 생성범위 지정


스프링 빈 설정

스프링 빈 설정 메타정보

XML 문서

  • XML 문서 형태로 빈의 설정 메타 정보를 기술
  • 단순하며 사용하기 쉬움
  • <bean> 태그를 통해 세밀한 제어 가능
<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="memberDao" class="com.test.hello.dao.MemberDaoImpl"></bean>

	<bean id="memberService" class="com.test.hello.service.MemberServiceImpl" scope="prototype">
  <property name="memberDao" ref="memberDao"></property>
	</bean>
  
</beans>

ApplicationContext.xml

Annotation

  • 어플리케이션의 규모가 커지고 빈의 개수가 많아질 경우 XML 파일 관리가 번거로움
  • 빈으로 사용될 클래스에 특별한 annotation을 부여해주면 자동으로 빈 등록 가능
  • "오브젝트 빈 스캐너"로 "빈 스캐닝"을 통해 자동 등록
    • 빈 스캐너는 기본적으로 클래스 이름을 빈의 아이디로 사용
    • 클래스 이름의 첫 글자는 소문자로 바꾼 후 사용
@Component
public class MemberServiceImpl implements MemberService {

	@Autowired
    private MemberDao memberDao;

	@Override
	public int registerMember(MemberDto memberDto) {
		return memberDao.registerMember(memberDto);
	}
}

Annotation으로 빈을 설정할 시, 반드시 component-scan을 설정해야 한다

<?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.3.xsd">

	<context:component-scan base-package="com.test.hello.*" />
  
</beans>

Stereotype Annotation 종류

  • 빈 자동등록에 사용할 수 있는 annotation
  • 빈 자동인식을 위한 annotation이 여러가지인 이유
    • 계층별로 빈의 특성이나 종류를 구분하기 위해
    • AOP Pointcut 표현식을 사용하면 특정 annotation이 달린 클래스만 설정 가능
    • 특정 계층의 빈에 부가기능을 부여하기 위해



DI - XML

Spring 설정

XML 문서 이용

  • Application에서 사용할 Spring 자원들을 설정하는 파일
  • Spring Container는 설정파일에 설정된 내용을 읽어 Application에서 피요한 기능을 제공함
  • Root tag는 <beans>
  • 파일명은 관계없음
<?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.3.xsd">
 
</beans>

applicationContext.xml

기본설정 - 빈 객체 생성 및 주입

  • 주입할 객체를 설정파일에 설정
    • : 스프링 컨테이너가 관리할 Bean 객체를 설정한다
  • 기본 속성
    • name : 주입 받을 곳에서 호출할 이름
    • id : 주입 받을 곳에서 호출할 이름(유일값)
    • class : 주입할 객체의 클래스
    • factory-method : Singleton 패턴으로 작성된 객체의 factory 메소드 호출

  <bean id="memberDao" class="com.test.hello.dao.MemberDaoImpl"></bean>

	<bean id="memberService" class="com.test.hello.service.MemberServiceImpl" scope="prototype">
  <property name="memberDao" ref="memberDao"></property>
	</bean>

applicationContext.xml

기본설정 - 빈 객체 얻기

  • 설정 파일에 설정한 bean을 Container가 제공하는 주입기 역할의 api를 통해 주입받는다.

		ApplicationContext context =
        new ClassPathXmlApplicationContext("com/ssafy/hello/di5/annotation/applicationContext.xml");
		CommonService memberService = context.getBean("memberServcie", MemberService.class);
        CommonService adminService = context.getBean("adminService", AdminService.class);

스프링 빈 의존관계 설정

Counstructor 이용

객체 또는 값을 통해 생성자를 주입받는다.
<constructor-arg> : <bean>의 하위태그로 설정한 bean 객체 또는 값을 생성자를 통해 주입하도록 설정
설정법 : <ref>, <value>와 같은 하위태그를 이용하여 설정하거나 속성을 이용하여 설정함.

  1. 하위 태그 이용

    • 객체 주입 시 : <ref bean="bean name"/>
    • 문자열(String), primitive data 주입 시 : <value>값</value>
      * type 속성 : 값은 기본적으로 String으로 처리. 값의 타입을 명시해야하는 경우 : <value type="int">10</value>
  2. 속성 이용

    • 객체 주입 시 : <constructor-arg ref="bean name"/>
    • 문자열(String), primitive data 주입 시 : <constructor-arg value="값"/>

생성자 주입 예시

Property 이용

프로퍼티를 통해 객체 또는 값을 주입받는다. - setter mothod (단, setter를 통해서는 하나의 값만 받을 수 있음)

<property> : <bean>의 하위태그로 설정한 bean 객체 또는 값을 property를 통해 주입하도록 설정함.

<ref>, <value>와 같은 하위태그를 이용해 설정하거나 속성을 이용하여 설정한다.

  1. 하위태그 이용
    • 객체 주입 시 : <ref bean="bean name"/>
    • 문자열(String), primitive data 주입 시 : <value>값</value>
  2. 속성 이용 : name - 값을 주입할 property 이름(setter의 이름)
    • 객체 주입 시 : <property name="propertyname" ref="bean name"/>
    • 문자열(String), primitive data 주입 시 : <property name="propertyname" value="값"/>
  3. xml namespace를 이용해 설정
    • <bean> 태그의 스키마 설정에 namespace 등록
    • Bean 설정 시 <bean> 태그의 속성으로 설정
      기본 데이터 주입 - p:propertyname="value"
      bean 주입 - p:propertyname-ref="bean_id"

Property 이용 예시



Collection 계열 주입

<constructor-arg> 또는 <property>의 하위 태그로 Collection 값을 설정하는 태그를 이용해 값 주입

  • 설정 태그

  • <props>
    • java.util.Properties에 값(문자열) 넣기
    • <prop>를 이용해 key-value를 properties에 등록함. 값은 태그 사이에 넣는다.



Annotation

Annotation : 멤버변수에 직접 정의하는 경우 setter method를 만들지 않아도 된다.

특정 Bean의 기능 수행을 위해 다른 Bean을 참조해야 하는 경우, annotation을 사용한다.

사용 예시


스프링 빈의 생명주기

0개의 댓글