Spring

[Spring] 의존성주입(DI)와 제어역행(IoC)

dearbeany 2022. 10. 11. 15:58
더보기

0. Framework에 대한 이해

1. DI, IoC 개념

2. Spring 개발환경 구축

3. Spring 환경설정

- 컨테이너에 객체 등록해서 객체 간의 의존관계 설정 

- 컨테이너로부터 원하는 자바코드로 객체를 회수해온다 

 

전략패턴을 통해 의존성을 해소?

*내가 쓰고자하는 클래스의 객체를 어떻게 스프링컨테이너에 등록하는지, 스프링컨테이너에 만들어둔 객체를 어떻게 받아다 쓰는지 알아야 한다.

 

  • DI (Dependency Injection)
    • 자바 내에서 객체를 생성하는 것이 아닌 외부에서(xml혹은 @Annotation)생성해서 주입
    • 자바 파일을 최대한 수정하지 않고 객체를 쉽게 관리하기 위함
    • 큰 규모의 프로젝트를 할 때 유리 (interface 처럼)
  • IOC 컨테이너
    • 인터페이스를 통해 객체들을 여러 개의 부품으로 만든다
    • IOC는 부품(객체)들을 담고있는 컨테이너
    • A객체가 IOC가 가지고 있는 부품 중에서 사용하고 싶은 부품을 선택해서 객체를 주입받을 수 있다.
  • 결국 스프링은
    • 부품을 생성하고 조립하는 라이브러리 집합테 (팩토리메소드의 역할)

 

의존성 주입이란 객체 간 연관 관계를 컨테이너가 직접 규정하는 것. 스프링 프레임워크에서는 각 클래스들의 연관관계를 클래스들 사이에서 맺는 것이 아니라 설정을 통해 맺어준다.

 

의존성 주입을 통해

(1) 클래스들 간의 의존 관계를 최소화하여 코드를 단순화 할 수 있다.

(2) 애플리케이션을 더 쉽게 유지 관리할 수 있다.

(3) 객체 생성, 소멸과 객체 간의 의존 관계를 컨테이너가 제어한다.

 

스프링에서 DI를 구현하기 위해 (1) XML이나 (2) Annotation 설정을 통해 제어한다.

스프링 프레임워크에서는 객체의 제어를 스프링 담당하므로 제어의 역전(개발자에서 스프링으로 넘어옴: IoC)이라고 한다.

 

 


 

<Maven을 이용해 Spring 라이브러리 세팅>

→ 스프링처럼 라이브러리가 의존관계가 복잡할수록 메이븐과 같은 빌드관리 도구를 사용하도록 한다.

 

1. 맨 처음 Java Project > 프로젝트 우클릭 > Configure > Convert to Maven project

2. mvnrepository.com 방문

https://mvnrepository.com/artifact/org.springframework/spring-context/5.3.18

3. pom.xml에 <build>태그가 끝나는 곳에 추가해준다.

  <dependencies>
  	<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-context</artifactId>
	    <version>5.3.18</version>
	</dependency>
  </dependencies>

4. 그러면 프로젝트 하위에 Maven Dependencies 가 추가되며 라이브러리가 세팅된 것을 확인할 수 있다.

 

<Spring 설정파일 만들고 객체(bean) 등록하기>

* 스프링에 등록되는 객체를 bean이라고 한다. bean들이 모여있는 설정파일이기에 <beans>라고 한다.

1. resources > applicationContext.xml 생성

2. xml파일에는 임포트의 개념이 없기 때문에 <bean class=""> 경로 작성 시에 풀 패키지명을 적어야 한다.

	<bean class="com.ssafy.spring.Desktop"></bean>

 

3. 위와 같이 작성 시 이 클래스로 만든 객체가 bean으로 등록 완료!

 

4. 이 객체를 얻어오려 할 때 이들을 구분할 수 있는 식별자가 필요하다. 식별자는 id를 사용.

	<bean class="com.ssafy.spring.Desktop" id="desktop"></bean>
	<bean class="com.ssafy.spring.Worker" id="worker"></bean>

 

 

 

<Spring 컨테이너 객체 빌드, 사용>

1. ApplicationContext : 인터페이스로, 스프링 컨테이너에 대한 규격임. 이 타입으로 객체를 만들도록 한다.

- 이 규격을 사용하여 구체화시켜서 다양한 클래스로 생성 가능.

 

2. getBean()은 파라미터로부터 받아오는 bean들이 무슨 타입에 상관없이 다 받아오므로 Object형을 반환한다. 따라서 그에 맞게 형변환 해주어야 한다.

 

 

 

기초 자료형이나 문자열, 상수 연결 시엔 value, 객체를 연결할 땐 ref를 사용

setComputer를 하지 않아도 객체 간의 의존관계 설정이 가능하다!

자바코드를 수정하지 않고도 설정파일만을 수정함으로써 Desktop > Laptop으로도 수정이 가능하다.

 

ex) 자바코드(Controller) 수정 없이 설정파일(.xml)만 수정함으로써 MySQLDao 에서 OracleDao로 변화가 가능하다.

전체 프로젝트에서 어디서도 new를 하지 않고 set, 설정파일 한 곳에서 모든 제어를 한다.

즉, 제어 역전을 통해 한 곳으로 모아모아 스프링컨테이너로 왔고, 의존성 주입을 통해 모든 객체 서로 간을 연결해주었다.

 

<applicationContext.xml>

	<bean class="com.ssafy.spring.Worker" id="worker">
		<property name="hong" value="27"></property>
		<property name="computer" ref="desktop"></property>
	</bean>

 

 

1. getBean("bean으로 등록한 클래스의 id명")으로 객체 가져오기

2. 컨테이너에 들어있는 bean 객체 간 의존관계 설정하는 법?

   (1) 설정자 주입 : <property name="setComputer의 set빼고 C는 소문자로 자동완성으로 가능" value="상수값" ref="또 다른 객체 연결 시"> 

   (2) 생성자 주입 : <constructor-arg name="생성자 변수명" value="상수값" ref="또 다른 객체 연결 시">  

   (3) Annotaion : <context:component-scan base-package="com.ssafy.spring"/> : 해당 패키지에 있는 낙인이 찍힌 클래스(@Component 가 박힌 클래스들)를 모두 bean으로 등록

 

* Annotation 방법

- 스프링 설정파일에서 구체적으로 bean을 등록하고 의존관계를 설정하는 방법X (1)(2)와 다름

- 단 (1)에서는 <bean>으로 등록한 클래스의 객체들을 가져올 때 id로 식별하였으나, (3)은 클래스 첫 글자를 소문자로 바꾼 이름을 bean의 이름으로 한다. (ex. Worker → worker)

- 의존관계? (1)은 <property> (2)는 <constructor-arg> 사용했다. (3)은 @Autowire를 사용했다. 이걸 붙이는 위치는 3군데가 있는데, 필드/생성자/프로퍼티 중 기본적으로 타입이 일치하는 bean을 찾아다가 넣어준다

 

 

 

더보기

사용하는 이유? 스프링이 객체를 관리하면..

- JDBC의 문제점인 (1)자원관리 (2)파라미터매핑 (3)결과값핸들링 문제점을 해결

- MVC연동도 편리해짐

 

참고: https://jonny-cho.github.io/spring/2018/11/07/spring-02/ https://vhxpffltm.tistory.com/151