UMC_2주차 과제

seonseon·2025년 9월 22일
0

연합동아리_umc

목록 보기
4/6

Servlet vs Spring MVC 비교

1. 전통적인 서블릿(Servlet) 기반 개발

HttpServlet을 상속받아 doGet(), doPost()를 오버라이딩하여 요청 처리

개발자가 요청 URL 매핑, 파라미터 추출, 비즈니스 로직 호출, 뷰 렌더링(HTML/ JSP forward)까지 직접 처리해야 함

코드 예시:

@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String name = req.getParameter("name");
        resp.setContentType("text/html");
        resp.getWriter().write("<h1>Hello, " + name + "</h1>");
    }
}

➡ 단점: URL 매핑, 파라미터 처리, 뷰 연결 등 반복적인 코드가 많아 유지보수가 어려움

2. Spring MVC

DispatcherServlet(Front Controller 패턴)이 모든 요청을 받아 처리

개발자는 비즈니스 로직과 요청 처리에만 집중 가능

애노테이션 기반 선언:


@Controller
public class HelloController {
    @GetMapping("/hello")
    public String hello(@RequestParam String name, Model model) {
        model.addAttribute("name", name);
        return "hello"; // 뷰 이름 (hello.jsp)
    }
}

Spring MVC 주요 구성 요소:

@Controller: 요청을 처리하는 클래스

@RequestMapping (또는 @GetMapping, @PostMapping): URL 매핑

DispatcherServlet: 요청을 받아 적절한 컨트롤러로 위임

➡ 장점: URL 매핑, 파라미터 바인딩, 뷰 연결, 예외 처리, 공통 기능 등을 프레임워크가 제공 → 개발자는 로직만 집중

3. Spring MVC가 서블릿보다 편리한 이유

Front Controller 패턴 적용: 모든 요청을 DispatcherServlet이 받아 일관된 처리

Annotation 기반 매핑: URL → 메서드 매핑 자동화

파라미터 자동 바인딩: @RequestParam, @ModelAttribute, DTO 변환 지원

뷰 처리 자동화: ViewResolver를 통해 JSP/Thymeleaf 템플릿 연결

AOP 기반 공통 처리 지원: Interceptor, ExceptionHandler, Filter 등 확장성

DI & IoC: Controller, Service, Repository 간 의존성 관리 용이

📌 DispatcherServlet 요청 처리 단계

Spring MVC는 Front Controller(DispatcherServlet)을 중심으로 동작한다.

처리 흐름 (단계별)

클라이언트 요청

사용자가 /hello 요청 → DispatcherServlet이 수신

HandlerMapping 조회

요청 URL과 매핑된 컨트롤러(@Controller 메서드) 검색

HandlerAdapter 실행

찾은 핸들러(메서드)를 실행할 수 있도록 어댑터 선택
(ex: RequestMappingHandlerAdapter)

Controller 호출

실제 비즈니스 로직 실행 후 ModelAndView 반환
(데이터 + 뷰 이름 포함)

ViewResolver 호출

뷰 이름(hello) → 물리적 뷰 경로(/WEB-INF/views/hello.jsp)로 변환

View 렌더링

JSP/Thymeleaf 엔진이 실행되어 HTML 응답 생성

클라이언트 응답 반환

최종 HTML이 사용자에게 전달

📊 다이어그램 (흐름도)

[Client Request]
       |
       v
[DispatcherServlet]  <-- Front Controller
       |
       v
[HandlerMapping] --- 요청 URL → 컨트롤러 매핑
       |
       v
[HandlerAdapter] --- 컨트롤러 실행 준비
       |
       v
[Controller] --- 비즈니스 로직 수행, ModelAndView 반환
       |
       v
[ViewResolver] --- 뷰 이름 → JSP/Thymeleaf 등 변환
       |
       v
[View(Render)] --- 최종 HTML 생성
       |
       v
[Client Response]

📌 Interceptor (추가 개념)

DispatcherServlet과 Controller 사이에서 공통 처리 담당

실행 단계:

preHandle() → Controller 실행 전 로직 (로그인 체크, 권한 확인)

postHandle() → Controller 실행 후, 뷰 렌더링 전 로직 (모델 데이터 가공)

afterCompletion() → 뷰 렌더링 후 로직 (리소스 해제, 로깅)

🌐 AOP(Aspect-Oriented Programming) 원리 탐구

1. AOP란 무엇인가? 왜 필요한가?

AOP(Aspect-Oriented Programming, 관점 지향 프로그래밍)은 핵심 로직(Core Concern)과 공통 관심사(Cross-cutting Concern)를 분리하기 위한 프로그래밍 기법이다.

공통 관심사란 여러 모듈에서 반복되는 기능(ex: 로깅, 트랜잭션, 보안, 성능 모니터링 등)을 의미한다.

OOP만으로는 비즈니스 로직과 공통 기능이 얽히면서 코드 중복과 유지보수 어려움이 생김 → AOP로 분리해 해결

2. OOP vs AOP 비교

구분OOP (객체 지향 프로그래밍)AOP (관점 지향 프로그래밍)
초점클래스 단위로 기능 모듈화횡단 관심사를 모듈화
중복 문제로깅, 보안, 트랜잭션 같은 공통 기능이 각 클래스에 중복 작성됨공통 기능을 Aspect로 분리, 여러 클래스에 일괄 적용
결과코드 중복 증가, 유지보수 어려움핵심 로직과 보조 기능이 분리 → 관심사 분리 (SoC)

3. AOP의 핵심 개념

JoinPoint

AOP 적용 가능한 지점 (ex: 메서드 실행 시점, 생성자 호출, 예외 발생)

Spring AOP에서는 메서드 실행 시점만 JoinPoint로 지원

Pointcut

어떤 JoinPoint에 Advice를 적용할지 정의한 표현식

예: execution( com.example.service..*(..))

Advice

실제 수행되는 공통 기능(횡단 관심사) 코드

종류:

@Before: 메서드 실행 전

@After: 메서드 실행 후

@AfterReturning: 정상 반환 후

@AfterThrowing: 예외 발생 후

@Around: 실행 전/후 모두 제어

Aspect

Pointcut + Advice의 결합체

공통 관심사를 모듈화한 클래스 (@Aspect로 선언)

Weaving

핵심 코드 + 횡단 관심사(Advice)를 결합하는 과정

시점에 따라 구분:

컴파일 타임 위빙: 컴파일 시점에 코드 삽입 (AspectJ)

로드 타임 위빙: 클래스 로더가 바이트코드 읽을 때 삽입

런타임 위빙: 프록시 객체를 생성해 실행 시점에 결합 (Spring AOP)

4. 런타임 위빙 vs 컴파일 타임 위빙

구분런타임 위빙 (Spring AOP)컴파일 타임 위빙 (AspectJ)
적용 시점실행 시점컴파일 시점
방식프록시 객체를 동적으로 생성하여 Advice 적용바이트코드 자체를 수정하여 Advice 삽입
특징Spring Bean에만 적용 가능 (메서드 실행 시점)더 강력, 필드 접근/생성자 호출 등 다양한 JoinPoint 지원
장점유연함, Spring IoC와 자연스럽게 통합강력한 기능 제공
단점메서드 실행 JoinPoint만 지원설정 복잡, 빌드 툴 필요

5. Spring AOP와 어노테이션 동작 방식

Spring AOP는 주로 프록시 기반 동작을 사용한다.

예시:

@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.example.service.*.*(..))")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("메서드 실행 전: " + joinPoint.getSignature().getName());
    }
}

동작 원리:

Spring 컨테이너가 @Aspect를 스캔

Pointcut에 매칭되는 메서드에 대해 프록시 객체를 생성

클라이언트가 메서드 호출 시, 실제 객체가 아닌 프록시를 거쳐서 실행됨

프록시가 Advice(공통 기능) → 실제 메서드 실행 → 사후 Advice 순으로 호출

6. Spring AOP의 프록시 패턴 활용 원리

Spring AOP는 내부적으로 프록시 패턴(Proxy Pattern)을 활용한다.

JDK Dynamic Proxy

인터페이스 기반 Proxy 생성

java.lang.reflect.Proxy 활용

CGLIB (Code Generation Library)

클래스 기반 Proxy 생성

상속을 통해 프록시 객체 생성 (final 클래스/메서드 불가)

📊 동작 흐름

[Client] 
   ↓ (메서드 호출)
[Proxy 객체] --- Advice 실행
   ↓ (실제 대상 객체 호출)
[Target Bean]
   ↓
[결과 반환]

0개의 댓글