IT탐험

의존성 주입과 제어의 역전 본문

게시판만들기기록/스프링 프레임워크

의존성 주입과 제어의 역전

watercase 2021. 10. 6. 11:15
  • 객체 지향 프로그래밍 언어에서 클래스는 특정 기능을 수행하는 부품 역할을 한다
  • 부품을 사용하다 이상이 있거나 더 좋은 부품이 생기면 교체해서 사용하는 것처럼 앱에서도 요구 사항에 따라 클래스 기능을 변경하거나 다른 클래스 기능으로 대체해야 하는 경우가 생기는데, 좀 더 수월하게 대체할 수 있게 도입된 기능이 의존성 주입( DI )과 제어 역행(IoC) 이다

의존성 주입 ( DI )

  • 어떤 클래스가 다른 클래스의 기능을 사용하려면 개발자가 직접 코드에서 사용할 클래스의 생성자를 호출해서 사용해야 한다. 즉, 사용할 클래스와 사용될 클래스의 관계는 개발자에 의해 직접 코드에서 부여된다
  • 의존성 주입 : 연관 관계를 개발자가 직접 컴포넌트(클래스)에 부여하는 것이 아니라 컨테이너가 연관 관계를 직접 규정하는 것
    • 의존성 주입을 통해 코드에서 직접적인 연관 관계가 발생하지 않으므로 각 클래스들의 변경이 자유로워진다 (약한 결합)
      • 프로그램은 각각의 독립적인 기능들로 구성되어 있는데 각 기능들은 세부 기능을 하는 여러 클래스들로 이루어진다. 이 때 특정 클래스에 변경 사항이 발생했을 때 그 클래스의 기능과 관련없는 다른 클래스까지 변경 해야 한다면 여러 문제가 발생할 수 있다. 서로 관련이 있는 기능들은 강하게 결합하고, 관련이 없는 기능들은 약하게 결합해야 좋은 프로그램이다
  • 스프링 프레임워크에서는 각 클래스들의 연관 관계를 클래스들 사이에서 맺는 것이 아니라 스프링 프레임워크에서 설정을 통해 맺어줌으로써 클래스들이 연관 관계를 갖지 않게 구현한다
    • 의존 관계를 약화시키기 위해 인터페이스를 활용할 수 있다. 하지만 인터페이스를 사용해도 클래스 자체는 소스 코드에서 직접 수정해야 한다
  • 의존성 주입을 적용하여 얻는 장점
    • 클래스들 간의 의존 관계를 최소화하여 코드를 단순화
    • 앱을 더 쉽게 유지 및 관리할 수 있다
    • 기존 구현 방법은 개발자가 직접 코드 안에서 객체의 생성과 소멸을 제어했지만 의존성 주입은 객체의 생성, 소멸과 객체 간의 의존 관계를 컨테이너가 제어
  • XML이나 애너테이션을 이용해 객체를 주입하여 객체들의 의존 관계를 맺어준다
  • 제어의 역전 ( IoC )
    • 기존 코드에서는 개발자가 직접 객체를 제어했지만 스프링 프레임워크에서는 객체의 제어를 스프링이 직접 담당하므로 제어의 역전( IoC )이라 한다
    • 일반적으로 DI로 IoC의 기능을 구현하므로 DI라는 용어를 더 많이 사용한다
  • 의존 (depandency)하는 객체를 컨테이너 실행 시 주입 (inject)하기 때문에 DI (Dependency Injection)라고 부른다
  • 각 클래스 객체를 bean이라고 부르는데, 이는 의존 관계를 설정하는 외부 XML 파일에서 각각의 객체를 <bean> 태그로 표시하기 때문
  • 의존 객체 주입 방식의 종류
    • 생성자를 이용하여 주입
    • setter를 이용하여 주입
    • 사용 예시
      • 더보기
        public class BoardServiceImpl implements BoardService {
        	private BoardDAO boardDAO;
        	public BoardServiceImpl(BoardDAO boardDAO) {
        		this.boardDAO = boardDAO; 
        // new를 사용해 객체를 생성하지 않고, 
        // 생성자를 호출할 때 컨테이너에 의해 주입되는 객체로 boardDAO 변수를 초기화
        	}
        }
        public class BoardServiceImpl implements BoardService {
        	private BoardDAO boardDAO;
        	public void setBoardDAO(BoardDAO boardDAO) {
        		this.boardDAO = boardDAO; 
        	}
        }
  •  <bean> 태그에 사용되는 속성
    • 속성 이름 설명
      id 빈 객체의 고유 이름으로, 빈 id를 이용해 빈에 접근
      name 객체의 별칭
      class 생성할 클래스, 패키지 이름까지 입력
      constructor-arg 생성자를 이용해 값을 주입할 때 사용
      property setter를 이용해 값을 주입할 때 사용
    • 사용 예시
      • 더보기
        <?xml version="1.0" encoding="UTF-8"?>
        <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
                                     "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
        <beans>
           <bean id="personService" class="com.spring.ex01.PersonServiceImpl">
              <property name="name">
                 <value>홍길동</value>
              </property>
           </bean>
        </beans>
        public interface PersonService {
        	public void sayHello();
        }
        public class PersonServiceImpl implements PersonService {
        	private String name;
        	private int age;
        	
        	public void setName(String name) {
        		this.name = name;
        	}
        	
        	@Override
        	public void sayHello() {
        		System.out.println("이름 : " + name);
        		System.out.println("나이 : " + age);
        	}
        }
        import org.springframework.beans.factory.BeanFactory;
        import org.springframework.beans.factory.xml.XmlBeanFactory;
        import org.springframework.core.io.FileSystemResource;
        
        public class PersonTest {
        	public static void main(String[] args) {
        		BeanFactory factory = new XmlBeanFactory(new FileSystemResource("person.xml"));
        		PersonService person = (PersonService) factory.getBean("personService");
        		person.sayHello();
        	}
        }
  • 빈에 주입되는 값으로 의존 관계에 있는 다른 빈을 주입하는 경우
    • 더보기
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
                                   "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
      <beans>
      	<bean id="memberService" class="com.spring.ex03.MemberServiceImpl">
      	   <property name="memberDAO" ref="memberDAO" />
      	</bean>
      	<bean id="memberDAO" class="com.spring.ex03.MemberDAOImpl" />
      </beans>
    • 의존하는 빈을 주입할 때는 주입되는 타입이 기본형 데이터가 아닌 참조형 데이터일 경우 ref 속성을 이용

'게시판만들기기록 > 스프링 프레임워크' 카테고리의 다른 글

스프링 JDBC  (0) 2021.10.07
스프링 MVC  (0) 2021.10.06
관점 지향 프로그래밍  (0) 2021.10.06
프레임워크란  (0) 2021.10.05
모델2  (0) 2021.10.05
Comments