[Spring] 스프링 프레임워크(Spring Framework)의 특징과 구조

DyungE_100·2022년 4월 8일
2

0. 스프링 프레임워크(Spring Framework)란?

동적 웹 사이트 개발을 위한 자바 플랫폼의 오픈 소스 애플리케이션 프레임워크다.
EJB를 사용할 때 알아야만 했던 수많은 디자인 패턴을 신경 쓸 필요없다. 스프링 프레임워크 그 자체로 이미 많은 디자인 패턴이 적용되어 배포되므로 스프링을 사용하는 것 자체가 디자인 패턴을 사용하는 것이다.

1. Spring Framework의 특징

스프링은 "IoC와 AOP를 지원하는 경량의 컨테이너 프레임워크"다.

  • 1) 경량적이다.

스프링은 여러 개의 모듈로 구성되어 있는 모듈식 프레임워크이다. 각 모듈은 하나 이상의 JAR 파일로 구성되어 있어 쉬운 개발과 실행이 가능하다. 또한 POJO(평범한 옛날 자바 객체, Plain Old Java Object) 형태로 객체를 관리해서 단순하고 가볍다.

  • 2) 제어의 역행(IoC, Inversion of Control)의존성 주입(DI, Dependency Injection)

스프링은 IoC를 통해 애플리케이션을 구성하는 객체 간의 낮은 결합도를 유지한다. IoC는 말 그대로 개발자가 직접 생성하거나 제어하는 것이 아닌 스프링의 Spring Bean모듈에서 객체를 생성하고 제어하며 관리하는 특징을 잘 설명해준다. (Bean 인스턴스를 생성해주는 곳은 Bean Factory라고 불린다.)

// 기존 Java
public class TV {
	private Speaker speaker;
    
    public TV(Speaker speaker) {
    	this.speaker = speaker;
    }
}

// Spring
@Component
public class TV {
	
    @Autowired
	private Speaker speaker;
}

DI는 객체 간의 의존성을 크게 줄여준다는 것에서 의미가 있다. 객체 간의 의존성이 줄어든다는 것은 그만큼 유지 보수를 할 때 손이 많이 가는 것을 줄여준다는 의미이기도 하다.

  • 3) 관점 지향 프로그래밍(AOP, Aspect Oriented Programming)

스프링은 비즈니스 메서드를 개발할 때 사용하는 공통 로직을 외부의 독립된 클래스로 분리하여, 해당 기능을 프로그램 코드에 직접 명시하지 않고 선언적으로 처리할 수 있다. 이로 인해 응집도가 높은 비즈니스 컴포넌트를 만들 수 있으며, 유지 보수 또한 높일 수 있다. OOP의 문제점 또한 보완할 수 있다.

  • 4) 컨테이너(Container)

컨테이너는 특정 객체의 생성과 관리를 담당하고 객체 운용에 필요한 다양한 기능을 제공한다. 대표적으로 Servlet과 Servlet Container가 그 예인데, Servlet 객체를 생성하고 생명 주기를 관리해주는 게 Servlet Container라는 맥락에서 스프링 또한 애플리케이션의 운용에 필요한 객체의 생성과 의존 관계를 관리한다는 점에서 일종의 컨테이너라고 할 수 있다.


2. Spring Framework의 구조

  • 1. Core Container

    서블릿의 생명 주기를 관리하는 서블릿 컨테이너와 비슷하게 bean의 생성과 관리를 해주는 container 역할을 한다.

    • 1) Spring Core

      Core 모듈은 DI와 Ioc 패턴을 적용할 수 있는 기본적인 스프링 프레임워크 클래스들을 포함하고 있다. 어떤 타입의 스프링 애플리케이션을 빌드하든 항상 직간접적으로 이 Spring Core에 대한 종속성을 가진다.

    • 2) Spring Bean

      Bean 모듈은 모든 bean 객체들의 생명 주기를 관리한다. Spring Bean이 갖고 있는 Bean Factory는 bean 인스턴스를 생성하거나 bean의 의존성 문제를 해결하는 역할을 담당하고 있다.

    • 3) Spring Context

      Spring Context는 Bean 객체들의 의존성 주입을 담당한다. 대부분의 경우 Spring 애플리케이션이 실행할 때, Spring Context 모듈은 실행되며 ApplicationContext로 불린다. (흔히 ApplicationContext.xml에 bean을 등록하여 의존성 주입해주는 역할을 해주는 모듈이라고 생각하면 편하다.)

    • 4) SpEL(Spring Expression Language)

      Runtime동안 object graph를 쿼링(querying)하고 실행하는데 도움을 준다.

  • 2. Data Access/Integration

    데이터베이스, XML 또는 Messaging을 포함한 다양한 형태의 데이터에 접근하기 용이하도록 하는 모듈들의 모음이다.

    • 1) Spring JDBC

      Spring JDBC는 Java JDBC API에 대한 추상화를 제공한다. 이러한 추상화와 함께 JdbcTemplate 또한 제공하여 데이터에 쉽게 접근 가능하도록 한다.

    • 2) Spring ORM

      Spring은 Hibernate, JPA와 같이 유명한 ORM 프레임워크를 제공해준다.

    • 3) Spring Transactions

      Spring Transactions Management API는 데이터베이스 뿐만 아니라 객체의 트랜잭션을 균일하게 관리해준다. 뿐만 아니라 프로그래밍 방식과 선언적 트랜잭션 관리를 모두 지원해준다.

  • 3. Web

    Web Application을 빌드할 때 사용하는 컴포넌트이다.

    • 1) Spring Web

      multipart file을 업로드하거나 IoC 컨테이너를 초기화 하는 등 기초적인 웹(Web)에 대한 부분들을 관리한다.
    • 2) Spring Web Servlet

      Web Servlet 모듈은 웹 애플리케이션 실행을 위한 MVC 구현이 포함되어 있다.
    • 3) Spring Web Sockets

      웹 애플리케이션에서 Web Sockets(웹 소켓)이란 클라이언트와 서버를 이어주는 터널이라고 생각하면 되는데 Spring Web Sockets은 이러한 Web Sockets을 구축하는데 도움을 준다.

그 밖에도 AOP, Aspects, Instrument, Test 그리고 Messaging 등과 구조로 나누어 볼 수 있다.

3. Spring Framework의 동작 과정

1. 클라이언트가 요청을 보내면 DispatcherServlet가 가로챈다.

클라이언트가 보낸 HTTP 요청을 보낼 때 아무 요청이나 가로채는 것은 아니고, web.xml의 에 등록된 내용을 토대로 가로채게 된다.

<servlet-mapping>
	<servlet-name>appServlet</servlet-name>
	<url-pattern>*.do</url-pattern>
</servlet-mapping>

위의 <url-pattern> 안에 있는대로 .do가 붙어야 한다. 'http://localhost8080/post/view.do'처럼 지정한 패턴이 web.xml에 들어있는 경우, DispatcherServlet은 요청을 가로채게 된다.

2. 가로챈 요청을 HandlerMapping에게 보내 해당 요청을 수행할 Controller를 찾는다.

@Controller
class HomeController {

    @RequestMapping(value = "/post/view")
    public String view() {
        return "";
    }
}

@Controller 어노테이션을 붙이면 Servlet-Context.xml에서는 이를 인식하여 Controller로 등록한다. HandlerMapping은 DispatcherServlet으로부터 요청을 전달받고, 해당 요청을 수행할 Controller를 찾는다. 수행할 Controller를 찾았다면 이번에는 HandlerAdapter가 Controller의 Method(@RequestMapping)를 인식하고 찾아가게 된다.

3. 실제 요청 처리

@Controller
public class HomeController {

	@RequestMapping(value = "/post/view")
	public String view() {
		
		// DB에서 포스팅 정보를 가져왔다는 가정한다.
		String title = "DB에서 조회한 포스팅 제목";
		String content = "DB에서 조회한 포스팅 내용";
		
		return "home";
	}
}  

Controller의 해당 Method에선 비즈니스 로직을 처리하게 되고 DB를 연동하는 클래스인 DAO를 따라 DB로부터 값을 가져온다.

4. ViewResolver를 통해 View 화면을 찾는다.

@Controller
public class HomeController {

	@RequestMapping(value = "/post/view")
	public String view() {
		
		// DB에서 포스팅 정보를 가져왔다는 가정한다.
		String title = "DB에서 조회한 포스팅 제목";
		String content = "DB에서 조회한 포스팅 내용";
        
		model.addAttribute("title", title);
		model.addAttribute("content", content);
		
		return "home";
	}
}

Model 객체를 이용하여 addAttribute 함수를 통해 화면에 보여줄 값들을 세팅하고 이를 return해준다. 이 때, "home"이라는 문자열은 Servlet-Context.xml에 설정된 prefix와 suffix 정보를 참조하여 /WEB-INF/views/home.jsp 파일을 찾는 정보를 제공한다.

Controller는 View와 View에 전달할 Model 객체를 DispatcherServlet으로 반환한다. ViewResolver는 Controller가 보내준 View의 이름을 토대로 View 화면을 찾게 된다.

5. ViewResolver가 찾은 View화면을 View로 보내주면 View는 처리 결과를 DispatcherServlet에 보내고, DispathcerServlet은 클라이언트에게 최종 결과를 보내준다.

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<html>
	<body>
		<h1>${title}</h1>

		<P>${content}</P>
	</body>
</html>

View화면(=home.jsp파일)은 Model 객체를 넘겨받고 그 Model 객체 안의 속성 값들을 ${} 기호에 표현된 부분으로 치환한다. 클라이언트는 처리가 모두 완료된 동적 웹 페이지를 최종적으로 넘겨 받게 된다.




책 <스프링 퀵 스타트>,
https://docs.spring.io/spring-framework/docs/4.0.x/spring-framework-reference/html/overview.html,
https://velog.io/@duckchanahn/Spring-%EC%9D%B4%EB%A1%A0%EC%A0%95%EB%A6%AC,
https://www.amitph.com/spring-framework-architecture/,
https://docs.spring.io/spring-framework/docs/4.0.x/spring-framework-reference/html/overview.html,
https://devpad.tistory.com/24, https://intro0517.tistory.com/151,

0개의 댓글