스프링 프레임워크(6) 의존성 주입

넙데데맨·2022년 4월 20일
0

의존성 주입

애플리케이션은 각각 기능 담당하는 컴포넌트로 이뤄짐
컴포넌트는 세부기능 수행하는 클래스로 이뤄짐
다른 클래스의 생성자를 호출해 사용할 경우 기능 구현 과정에서 빠르게 대처하기 힘들다.
스프링 프레임워크에서는 각 클래스 연관 관계를 스프링 설정을 통해 맺어줘 클래스들이 연관 관계를 갖지 않게 구현한다.

의존성 주입 사용전

boardController.java

	public class BoardController extends HttpServlet{
    	BoardService boardService;
        
        public void init() throws ServletException{
        	boardService = new BoardService();
        }
	}

boardService 클래스의 기능을 사용하기 위해 생성자 호출해 boardService 객체를 코드에서 직접 생성해 사용
BoardService.java

	public class BoardService{
    	boardDAO boardDAO;
    	public BoardService(){
        	boardDAO = new BoardDAO;
        }
    }

boardService 역시 마찬가지로 boardDAO 클래스 사용 위해 객체 직접 생성
boardDAO의 클래스 기능 변경 시 연관된 클래스들을 전부 변경해줘야할 수도 있다.

인터페이스 적용 게시판 기능

boardServiceImpl.java

	public class BoardServiceImpl implments BoardService{
    	BoardDAO boardDAO;
    	public BoardService(){
        	boardDAO = new BoardOracleDAOImpl; // BoardDAO 구현 클래스
        }
    }

중간에 MySQL로 DB가 바뀔 시

//boardDAO = new BoardOracleDAOImpl;
boardDAO = new BoardMySQLDAOImpl;

해당 부분만 교체해주면 된다. 하지만 소스코드에서 직접 수정해야하는 불편함이 잇다.

의존성 주입 적용 게시판 기능

boardServiceImpl.java

	public class BoardServiceImpl implments BoardService{
    	private BoardDAO boardDAO;
    	public BoardServiceImpl(BoardDAO boardDAO){
        	this.boardDAO = boardDAO;
        }
    }

boardServiceImpl 클래스는 생성자를 호출할 때 컨테이너에 의해 주입되는 객체로 boardDAO 변수를 초기화한다.
이처럼 의존하는 객체를 컨테이너 실행 시 주입하기 때문에 DI라고 부른다. 의존성 주입 방식에는 생성자를 통한 방식과 setter를 통한 주입 방식이 있다.

1. 값 형식 DI

<bean id="exam" class="spring.di.entity.NewlecExam">
  <property name="kor" value="10"/>
  <property name="eng" value="20"/>
  <property name="math" value="30"/>
  <property name="com" value="40"/>
</bean>

<bean id="console" class="spring.di.ui.InlineExamConsole">
  <property name="exam" ref="exam"/>
</bean>

2. 생성자 DI

KimExam.java

	public KimExam(int kor, int eng, int math, int com) {
		this.kor = kor;
		this.eng = eng;
		this.math = math;
		this.com = com;
	}

setting.xml

	<bean id="exam" class="spring.di.entity.NewlecExam">
	  <constructor-arg value="10" />
	  <constructor-arg value="20" />
	  <constructor-arg value="30" />
	  <constructor-arg value="40" />
	</bean>

문제 어떤 필드를 초기화하는 지 알기 쉽지 않다!

	<bean id="exam" class="spring.di.entity.NewlecExam">
	  <constructor-arg index="0" value="10" />
	  <constructor-arg index="1" value="20" />
	  <constructor-arg index="3" value="30" />
	  <constructor-arg index="2" value="40" />
	</bean>
	<bean id="exam" class="spring.di.entity.NewlecExam">
	  <constructor-arg name="kor" value="10" />
	  <constructor-arg name="eng" value="20" />
	</bean>

문제 어떤 타입인지 알 수 없다.

	<bean id="exam" class="spring.di.entity.NewlecExam">
	  <constructor-arg name="kor" type="float" value="10" />
	  <constructor-arg name="eng" type="int: value="20" />
	</bean>

설정 파일 처리기 추가


1. xml 파일의 Namespaces 탭 p에 체크

2.beans 태그에xmlns:p="http://www.springframework.org/schema/p" 처리기가 추가됨
3.

<bean id="exam" class="spring.di.entity.NewlecExam" p:kor="10"/>

namespace p 추가

namespace
같은 이름을 가진 것들을 구분하기 위한 것
위 코드의 p:kor 는 p가 처리할 kor 이라는 뜻
태그나 일반 속성에 사용이 가능하다.
bean의 하위 태그인 property 태그 대신 네임스페이스 p를 이용해 bean태그의 속성에서 바로 값을 입력할 수 있다.

3. 컬렉션 생성과 목록 DI

Java 코드

List<Exam> exams = new ArrayList<>();
exams.add(new NewlecExam(1,1,1,1));
for(Exam e : exams) System.out.println(e);

List에 추가하기 위해 쓰이는 add 메서드 기능을
xml 파일에서 property에서 사용할 수가 없다.

ArrayList는 생성자에 Collection을 대입할 수 있다.

<bean id="exams" class="java.util.ArrayList">
	<constructor-arg>
		<list>
			<bean class="spring.di.entity.NewlecExam" p:kor="10" p:eng="10"/>
			<ref bean="exam"/>
		</list>
	</constructor-arg>
</bean>	

namespace util 추가

<util:list id="exams" list-class="java.util.ArrayList">
	<bean class="spring.di.entity.NewlecExam" p:kor="20" p:eng=""/>
	<ref bean="exam"/>
</util:list>

차이점 : namespace util을 사용 시 실제로 객체를 만들 수가 있다.

리스트 추가 방법
<bean class="spring.di.entity.NewlecExam" p:kor="10" p:eng="10"/>
리스트 안에 집어넣는 것이기 때문에 id 속성은 필요 없다.
<ref bean="exam"/>
이미 만들어진 객체를 참조하여 넣을 수도 있다.

알아본 것

xml 파일을 통해 객체를 초기화 사용하는 법

  • 값 DI
  • 생성자 DI

namespace를 통한 초기화 및 리스트 초기화

  • p : 타입을 알아서 넣어주는 네임스페이스
  • util

property를 사용할 땐 해당 객체의 setter 함수를 사용
constructor-arg를 사용할 땐 해당 객체의 생성자를 사용해 값을 주입해준다

profile
차근차근

2개의 댓글

comment-user-thumbnail
2022년 4월 21일

잘보고갑니다

1개의 답글