BackEnd/Spring

Spring_국비Day81

Leo.K 2022. 6. 27. 17:20

프레임워크는 기본 틀을 만들어 놓은 상태에서 이 틀과 나의 코드를 조립하여 완성하는 것이다. 따라서 나의 코드를 Spring에서 준비해준 기본 틀과 알맞게 조립하기 위해서는 기본 틀을 이해할 필요가 있다.

[ 스프링의 개요 ]

Spring 프레임워크는 JavaEE 기반의 어플리케이션 개발을 쉽게 해주는 오픈소스 어플리케이션 프레임워크로, 간단한 자바 객체(POJO : Plain Old Java Object) 를 Spring의 경량(Lightweight) 컨테이너를 통해 생성 및 관리하는 빈(Bean) 으로 처리해준다.

  • Spring이라는 이름의 기원은 전통적인 J2EE를 “겨울”에 빗대어 “겨울” 후의 “봄”으로 새로운 시작을 의미함 
  • Rod Johnson이 창시한 개발프레임워크
  • EJB가 제공했던 대부분의 기능을 일반 POJO(Plain Old Java Object)를 사용하여 개발할 수 있도록 지원함 
  • 엔터프라이즈 어플리케이션 개발의 복잡성을 줄이기 위한 목적으로 개발됨
  • 소프트웨어를 편하게 개발할 수있도록 도와주는 도구.

 

IoC(Inversion Of Control) Container : 제어의 역전

  • 프레임워크의 기본적인 기능인 IoC(Inversion of Control) Container 기능을 제공하는 서비스이다.
  • 객체의 생성 시, 객체가 참조하고 있는 타 객체에 대한 의존성을 소스 코드 내부에서 하드 코딩하는 것이 아닌, 소스 코드 외부에서 설정하게 함으로써, 유연성 및 확장성을 향상시킨다.
  • 주요 기능 : Dependency Injection(의존성 주입), Bean Lifecycle Management
  • 오픈소스 : Spring Framework 3.2.의 IoC Container를 수정없이 사용한다.
  • 의존성 관리의 중요성
  • IoC는 Inversion of Control의 약자로 한글로 “제어의 역전” 또는 “역제어”라고 부른다. 어떤 모듈이 제어를 가진 다는 것은 “어떤 모듈을 사용할 것인지”, “모듈의 함수는 언제 호출할 것인지” 등을 스스로 결정한다는 것을 의 미한다. 이러한 제어가 역전되었다는 것은, 어떤 모듈이 사용할 모듈을 스스로 결정하는 것이 아니라 다른 모듈 에게 선택권을 넘겨준다는 것을 의미한다.

DI(Dependency Injection)

  • Dependency Injection이란 모듈간의 의존성을 모듈의 외부(컨테이너)에서 주입시켜주는 기능으로 Inversion of Control의 한 종류이다.
  • 런타임시 사용하게 될 의존대상과의 관계를 Spring Framework 이 총체적으로 결정하고 그 결정된 의존특징을 런타임시 부여한다.

Non-IoC/DI : 지금까지는 Foo가 Bar & Baz가 필요하기 때문에 프로그램 런타임시에 직접 객체를 생성해서 사용했다. Bar & Baz를 Foo가 직접 생성했다.  EX) 떡볶이를 만들 때(조리할 때 = 프로그램이 시작할 때), 떡과 고추장이 필요하면 직접 재료를 준비해서 Foo가 조리한다.

IoC/DI : 스프링을 사용하면 프로그램을 시작하기 전에 Foo를 만들 때, Bar & Baz를 미리 생성하고, Foo에게 주입해준다. Bar & Baz를 제3자인 스프링이 직접 생성했다. EX) 떡볶이를 만들기 위한 레시피가 존재하기 때문에 프로그램 시작시에 이 레시피를 스프링에게 전달하면, 스프링이 프로그램이 시작(떡볶이 조리)전에 재료를 미리 준비해준다. 스프링을 사용하면 미리 설계한대로 모든 객체를 스프링이 생성해서 준비한다. 이때, Foo는 Bar&Baz가 있어야 필요한 작업을 할 수 있기 때문에 Foo는 Bar&Baz에 의존적이고, 이러한 의존성을 스프링이 프로그램 시작 전에 주입해주는 것이다. 이를 의존성주입(DI)라고 한다.

스프링 부트 : 좀 더 빠른 개발을 위해서 환경설정까지 스프링 부트가 모두 해준다. 관리 프로그램으로 Gradle을 사용한다.

스프링 프레임워크(레거시) : 환경설정의 어려움이 있지만, 가장 전통적인 방법이다. maven을 사용한다.

하지만 무슨 환경설정이 필요한지 알아야 더 좋은 버전으로 빠른 개발을 할 수 있는 것이기 때문에, 스프링 레거시 프로젝트를 학습하고 이후에 스프링 부트를 학습하는 것이 좋다.

현재 나와있는 버전은 sts tools4.x 버전인데, 4부터는 레거시를 지원하지 않고, boot만 지원하기 때문에, 필자는 기 사용하던 이클립스에서 sts 플러그인을 추가로 설치해서 사용하기로 했다. 

Help -> Eclipse Marketplace -> search -> spring sts 검색 -> Spring Tools 4 Add-On for Spring Tools 4 3.9.22.RELEASE  버전을 설치한다. 

 

성공적으로 플러그인이 설치되었다면, perspective를 spring으로 변경한다. 변경하면 가장 처음 프로젝트를 만드는 것이 가장 중요하다. 아래의 이미지와 같이 Spring Legacy Project를 생성한다. Spring Starter Project가 위에서 언급한 Spring boot이다.

 

프로젝트를 생성할때는 반드시 Spring MVC Project로 생성을 해야한다. next를 누르면 추가 설치가 필요하다고 나오는데 yes를 누르고, 패키지를 지정해야 하는데, 이는 최소 3개로 구성되어야 한다. 예제를 위해 com.ict.myapp라고 입력하자. 

com.ict는 groupid를 지칭하는 경로이고, myapp은 애플리케이션 id를 지칭하는 경로이다. 패키지를 설정하고 finish 버튼을 누르면 잠깐의 추가 라이브러리 설치 후에 성공적으로 프로젝트 생성이 완료된다.

 

[ 스프링 프로젝트의 편집 폴더 구조 ]

 

[ maven 프로젝트의 편집 폴더 구조 ]

 

[ pom.xml 파일에 환경설정한 대로 실행파일 만들기 ]

실행파일을 만들기 위해 필요한 라이브러리를 다운로드 받는다. 결과는 target폴더에 실핼폴더인 war파일이 다운로드 된다.

이렇게 clean을 하는 순간 target폴더에 만들어 두었던 war파일이 삭제된다.

 

[ 의존성 주입 ]

 

[ Spring의 사용영역 ]

실제는 그림과 약간 다르다. 스프링은 Dispatcher Servlet이라는 단 하나의 컨트롤러를 가진다. 아래 이미지는 영역에 대한 이해를 위함이라고 생각하자.

 

[ Spring 초기화 ]

가장 처음 프로젝트를 실행하면 toacat이 실행되면서 web.xml에 있는 환경설정 파일을 읽어와 파일의 내용대로 서버를 초기화한다. 이때, 리스너 객체인 ContextLoaderListener(Spring 객체)가 생성이 되고, 이 객체가 root-context.xml에 정의되어 있는 Bean객체를 생성한다. 이때, root-context.xml는 개발자가 직접 설계해야 한다.

 

1. [ 스프링이 객체를 생성하는 법 ] -> bean - Constructor Injection(생성자를 통해 의존성 즉, 객체를 주입해주는 방법)

1
2
3
4
5
6
7
8
9
<!-- Constructor Injection, 생성자 주입 -->
<!-- PersonVo p1 = new PersonVo("이길동", 20, "010-111-1234") -->
<!-- 외부에서 전달되는 인자를 파라미터, 내부에서 지칭하는 것을 아규먼트(argument)라고 한다. -->
<!-- index와 type은 생략 가능하다./ -->
<bean id="p1" class="vo.PersonVo">
    <constructor-arg value="이길동"            index="0"        type="java.lang.String"/>
    <constructor-arg value="20"                index="1"        type="int"/>
    <constructor-arg value="010-111-1234"    index="2"        type="java.lang.String"/>
</bean>
cs

 

2. [ 스프링이 객체를 생성하는 법 ] -> bean - Setter Injection(세터 메서드를 통해 필요한 객체를 주입해주는 방법)

1
2
3
4
5
6
7
8
9
10
11
12
<!-- Setter Injection -->
<!-- PersonVo p2 = new Person();
     p2.setName("이길동");
     p2.setAge(20);
     p2.setTel("010-222-1234");
 -->
<bean id="p2" class="vo.PersonVo">
    <!-- p2.setName("이길동"); -->
    <property name="name" value="이길동" />
    <property name="age" value="30" />
    <property name="tel" value="010-222-1234" />
</bean>
cs

 

3. [ 이미 생성된 객체를 주입하는 방법 ].feat beansGraph

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<!-- String nameBean = new String("삼길동") -->
<bean id="nameBean" class="java.lang.String">
    <constructor-arg value="삼길동" />
</bean>
 
<!-- Integer ageBean = new Integer(30) -->
<bean id="ageBean" class="java.lang.Integer">
    <constructor-arg value="30" />
</bean>
 
<!-- String telBean = new String("010-123-1234") -->
<bean id="telBean" class="java.lang.String">
    <constructor-arg value="010-333-1234"/>
</bean>
 
<!-- Setter Injection -->
<bean id="p3" class="vo.PersonVo">
    <property name="name" ref="nameBean"/>
    <property name="age" ref="ageBean"/>
    <property name="tel" ref="telBean"/>
</bean>
 
<!-- Constructor Injection -->
<bean id="p4" class="vo.PersonVo">
    <constructor-arg ref="nameBean"/>
    <constructor-arg ref="ageBean"/>
    <constructor-arg ref="telBean"/>
</bean>
cs

                          

[ Maven library ]

같은 프로젝트라도 다른 컴퓨터에서 작업하던 내용을 나의 컴퓨터에서 옮겨와 실행을 할때 오류가 나면, maven라이브러리가 다르거나 충돌이 나서 발생할 수 있는 경우이다. 이때는 C:\Users\사용자의폴더\.m2\repository를 삭제시키고 프로젝트를 새로 실행시키면, 아래의 이미지처럼 중앙 repository에서 필요한 라이브러리를 다운받아 온다.

'BackEnd > Spring' 카테고리의 다른 글

SpringCollection_국비Day82  (0) 2022.06.28
Spring학습_Day4_AOP  (0) 2022.06.28
Spring 학습_Day3_IoC_DI  (0) 2022.06.20
Spring 학습 Day2_개발환경 구축  (0) 2022.06.18
Spring 학습 Day1_개요 및 특징  (0) 2022.06.18