5 minute read

Spring 기본

Spring vs Spring MVC vs Spring boot

  • Spring : Java 기반 웹 어플리케이션 개발을 위한 오픈소스 프레임워크이다.

Spring은 plain old java objects - POJOs에 직접 침투하지 않고 이로부터 어플리케이션을 만들 수 있게 한다.
따라서, Spring을 사용한다면 얻을 수 있는 이점은 다음과 같다.

  1. transaction API에 관여하지 않고, DB 트랜잭션을 사용하는 Java 메서드를 실행할 수 있다.
  2. remote API에 관여하지 않고, 로컬 자바 메소드를 remote 프로시저로 만들 수 있다.
  3. JMX API에 관여하지 않고, 로컬 자바 메서드를 management operation으로 만들 수 있다.
  4. JMS API에 관여하지 않고, 로컬 자바 메서드를 메시지 핸들러로 만들 수 있다.
  • Spring MVC : Spring을 통한 웹 개발에서 MVC를 적용할 수 있도록 제공하는 프레임워크
  • Spring boot : Spring 설정을 자동화하는 Spring 기반 프레임워크
  Spring MVC Spring Boot
설정 XML 파일에 설정 @ 어노테이션을 사용한 자동화된 설정
WAS 별도의 WAS 설치 필요 내장된 Tomcat 등의 WAS 사용 가능
의존성 개별적으로 추가해야 함 초기 의존성 설정에 포함되어 있음
구성요소 Dispatcher Servlet, Handler Mapping, View Resolver 등 자동 구성되는 스프링 기반 구성요소 (예: Spring Web MVC)
개발 방법론 전통적인 웹 개발 방식 빠르고 간편한 웹 개발 방식

MVC1 vs MVC2

  • MVC란, 모델 - 뷰- 컨트롤러의 세가지 요소로 나누어진 패턴을 의미한다.
    • Model
      • 어플리케이션의 정보나 데이터, DB 등 모든 데이터 정보를 가공해 가지는 컴포넌트이다.
    • View
      • 정제된 데이터를 활용해 사용자에게 보여지는 리소스
    • Controller
      • 데이터와 비즈니스 로직 사이의 흐름 제어
      • MVC 패턴에서 뷰와 모델이 직접적인 상호작용을 하지 않도록 관리한다.
  • SpringMVC에서는 프론트 컨트롤러가 Dispatcher Servlet이다.

MVC1

  • View, Controller를 모두 JSP가 담당하므로 구현 난이도는 쉬운 편
  • 프로젝트가 커질수록 재사용성이 떨어지고, 가독성 또한 떨어진다.
    • 유지보수 문제 발생

MVC2

  • 요청을 Servlet에서 먼저 받는다. (View, Controller가 분리되어 있다.)
  • 수정사항 발생시 Model, View, Controller에서 각 부분에서 반영해야할 수정사항만 꺼내어 수정하면 된다.
    • 유지보수에서 큰 이점을 가진다.
  • Spring에서 해당 패턴을 채택하였다.

dispatcher servlet

  • Spring MVC의 Front Controller
  • Tomcat과 같은 서블릿 컨테이너를 통해 생명 주기가 관리된다
  • HttpServlet을 상속받아 사용한다.
  • 클라이언트의 요청을 가장 먼저 받아들인다.
  • 요청을 적절한 핸들러로 보낸다.

Dispatcher Servlet의 동작 방식

  • 클라이언트 요청이 들어오면, Dispatcher Servlet이 이를 받아들인다.
  • Dispatcher Servlet은 해당 요청을 처리하기 위해 HandlerMapping 객체를 이용해 요청과 매핑되는 controller을 검색한다.
  • Handler Adapter가 요청에 맞는 ModleAndView 를 반환한다. (컨트롤러에서)
  • ModelAndView 객체에서 View name에 맞는 이름을 검색하여 view를 만들어 Dispatcher Servlet에게 결과를 반환한다.
  • Dispatcher Servlet은 해당 결과를 적절한 뷰에게 전달한다.
  • 뷰는 최종적으로 클라이언트에게 응답을 보낸다.

Dispatcher Servlet의 설정 방법

  • web.xml 파일에 Dispatcher Servlet을 등록할 수 있다.

Dispatcher Servlet의 역할

  • HTTP 요청의 적절한 처리를 위한 컨트롤러 핸들러에 요청을 전달
  • 컨트롤러 핸들러가 요청을 처리한 결과를 적절한 뷰에 전달
  • 요청 처리 과정에서 발생하는 예외 처리

DI와 IoC

IoC (Inversion Of Control)

  • 메소드나 객체의 호출 작업을 개발자가 결정하지 않고 외부(Spring) 컨테이너에서 결정
  • 의존성을 역전시켜 객체간 결합도를 줄이고 유연한 코드를 작성할 수 있게 한다.
    • 가독성을 좋게 하고 코드 중복도를 낮추며, 유지보수를 편하게 할 수 있게 한다.
  • 기존 순서 : 객체 생성 -> 의존성 객체 생성 -> 의존성 객체 메소드 호출
  • Spring : 객체 생성 -> 의존성 객체 주입 -> 의존성 객체 메소드 호출
  • 모든 의존성 객체를 Spring 실행시 생성하고, 필요한 곳에 주입시킴 (싱글톤 패턴)

IoC 컨테이너

  • 객체의 생성/관리/의존성 등… 모든 관리를 IoC 컨테이너에서 제어한다.
  • 기본적으로 객체를 생성하고 객체간의 의존성을 이어주는 역할을 한다.
  • ApplicationContext
    • Bean을 등록, 생성, 조회, 반환 관리
    • 스프링의 각종 부가 기능을 추가로 제공
      • 텍스트 메시지 관리, 이미지 자원 포괄적인 관리, 리스너 빈에 이벤트 발생 알림 등…
    • 보통 BeanFactory의 확장 인터페이스인 ApplicationContext를 사용한다.
  • Bean Factory
    • Bean을 등록, 생성, 조회, 반환 관리
    • 단순히 컨테이너에서 객체를 생성하고 DI를 처리하는 기능만 제공
    • 팩토리 디자인 패턴의 구현체로 빈을 생성하고 분배하는 책임을 진다.
    • Bean을 조회할 수 있는 getBean() 메소드가 정의되어 있다.

빈(Bean) 요청 시 처리 과정

클라이언트에서 해당 빈을 요청하면 ApplicationContext는 다음과 같은 과정을 거쳐 빈을 반환한다.

  1. ApplicationContext@Configuration이 붙은 클래스들을 설정 정보로 등록해두고, @Bean이 붙은 메소드의 이름으로 빈 목록을 생성한다.
  2. 클라이언트가 해당 빈을 요청한다.
  3. ApplicationContext는 자신의 빈 목록에서 요청한 이름이 있는지 찾는다.
  4. ApplicationContext는 설정 클래스로부터 빈 생성을 요청하고, 생성된 빈을 돌려준다.

DI(Dependency Injection)

  • 스프링의 의존 관계 주입 기능
  • 디자인 패턴 등이 적용된 객체를 직접 작성 및 생성하지 않고, Spring에서 생성한 후 주입시켜주는 방식
  • 모듈간 결합도가 낮아지고 유연성이 높아진다.
  • Spring 프레임워크에서는 Setter Injection, Constructor Injection 두 가지 방식이 있다.

  • DL(Dependency Lookup) : 컨테이너에서 제공하는 API를 이용해 사용하고자 하는 빈(Bean)을 저장소에서 Lookup하는 것을 말한다.

모듈

Spring Framework는 약 20개의 모듈로 구성되어 있으며, 이 모듈들은 각기 Core Container, Data Access/Integration, Web, AOP (Aspect Oriented Programming), Instrumentation, Test 의 그룹으로 묶여있다.

Bean, Component

  • @Component
    • 싱글톤 클래스 빈을 생성하는 어노테이션
    • 선언적인 어노테이션
  • @Bean
    • 스프링에서 Bean으로 등록하고자 하는 객체에 메소드 레벨로 추가하는 어노테이션이다.
    • 개발자가 컨트롤이 가능한 범위 내에서 Bean의 Scope을 설정할 수 있다.
구분 Bean Component
사용 대상 메소드에 사용 클래스에 사용
사용 범위(Scope) 개발자가 직접 컨트롤 가능 개발자가 컨트롤 불가능
외부 라이브러리 사용시 사용 X O
내부 클래스에 사용 X O
@Configuration
public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}

  • @Configuration 어노테이션이 붙은 자바 설정 파일을 생성한다.
  • @Bean 어노테이션이 붙은 메소드는 MyService인터페이스를 구현한 MyServiceImpl 객체를 돌려준다.
public class App {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        MyService myService = context.getBean(MyService.class);
        myService.doSomething();
    }
}
  • ApplicationContext를 사용해 빈을 가져올 수 있다.

  • @Component는 Class Level에서, @Bean은 Method Level에서 적용된다.
  • @Bean은 사용자가 컨트롤 하지 못하는 Class나, 좀 더 유연하게 객체를 생성해서 넘기고 싶을 때 (이를 테면 외부 라이브러리) 사용한다.
  • @Component는 Class 자체를 빈으로 등록하고 싶을 때 사용한다.
  • @SpringBootApplication@Configuration, @ComponentScan을 상속받고 있다.

@Component, @Service, @Controller

구분 @Component @Service @Controller
역할 Spring에서 관리되는 객체임을 표시하기 위해 사용하는 가장 기본적인 annotation 서비스 컨트롤러
사용 예시 DAO, Repository 등에 사용 비즈니스 로직에 사용 MVC 패턴에서 컨트롤러에 사용
역할 분리 역할 분리하지 않음 서비스 계층 역할 분리 웹 요청을 처리하는 컨트롤러 계층 역할 분리
스프링 AOP 지원 X O O
  • Component vs Controller/Service/Repository
    • 일반적으로 컴포넌트 클래스들에 @Component를 붙일 수 있으나, @Repository, @Service, @Controller를 붙여 클래스들을 처리하는데 더 적합하도록 할 수 있고 관점(aspects)에 더 연관성을 부여할 수 있다. (= AOP 를 통한 처리가 쉽게 가능하다)

Container

  • ApplicationContext
    • 직접 오브젝트를 생성하고 관계를 맺어주는 코드가 없고, 그런 생성 정보와 연관관계 정보에 대한 설정을 읽어 처리한다.
  • IoC 컨테이너
    • 객체에 대한 생성 및 생명주기를 관리할 수 있는 기능을 제공
    • IoC Container는 오브젝트의 생성과 관계설정, 사용, 제거 등의 작업을 대신 해준다하여 붙여진 이름이다.
    • 이때, IoC Container에 의해 관리되는 오브젝트들은 Bean 이라 한다.

VO vs DTO vs DAO

VO(Value Object)

  • Read-Only 속성을 지닌 값 오브젝트
  • @Getter만을 가진다.
  • 리터럴 값 개념이다.
    • 두 객체의 모든 필드 값이 동일하면 두 객체는 같게 여겨진다.

DTO(Data Transfer Object)

  • 계층 간 데이터 교환을 하기 위해 사용하는 객체 - 이에서 계층은 컨트롤러, 뷰, 비즈니스 로직, persistent layer 가 있다.
  • 로직을 가지지 않는 순수한 데이터 객체(Java Bean)
  • @Getter, @Setter만을 가지는 클래스

DAO(Data Access Object)

  • 실제로 DB의 데이터에 접근하기 위한 객체
  • CRUD 기능을 수행
  • Service와 DB를 연결하는 고리 역할
  • 데이터 베이스 접근을 위한 로직과 비즈니스 로직을 분리하기 위해서 사용된다.
  • JPA에서는 JpaRepository를 상속받는 Repository 객체가 DAO가 된다.

출처

  • https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/
  • https://www.baeldung.com/spring-bean

Leave a comment