[SB 3기] 코드잇 스프린트 위클리페이퍼 6주차

JHLee·2025년 5월 18일
post-thumbnail

Q. Spring에서 AOP(Aspect Oriented Programming)가 필요한 이유와 이를 활용한 실제 애플리케이션 개발 사례에 대해 설명하세요.

✅ AOP란?

AOP(Aspect Oriented Programming, 관점 지향 프로그래밍)란 공통된 관심사를 기준으로 하나의 모듈로 분리하는 것을 말한다.

이는 OOP(Object Oriented Programming, 객체 지향 프로그래밍)의 한계를 보완하기 위한 방법론으로, 핵심 비즈니스 로직과는 별개로 반복적으로 사용되는 부가 기능(로깅, 보안, 트랜잭션 처리 등)을 하나의 모듈(Aspect)로 분리하여 재사용성과 유지보수성을 높일 수 있다.

❓ AOP가 필요한 이유

OOP를 기반으로 애플리케이션을 설계하다 보면 여러 클래스(모듈)에서 반복적으로 등장하는 공통 로직들이 존재하게 된다.
이러한 로직들을 각 클래스에 직접 작성할 경우 중복되는 코드가 늘어나고, 이는 코드의 가독성과 유지보수성을 크게 떨어뜨릴 수 있다.

AOP를 활용하여 이러한 공통 로직들을 각각의 모듈로 분리하여 관리하면 코드의 중복을 줄이고, 코드의 가독성과 유지보수성을 개선할 수 있다. 또한, 공통 기능 코드 수정도 더욱 수월해진다.

➕ 이를 활용한 실제 애플리케이션 개발 사례

Spring은 @AspectJ 스타일의 AOP를 지원하며, AspectJ 전체 기능 중 프록시 기반 AOP(Proxy-based AOP)를 기본 제공한다.

  1. 로깅(Logging)
    비지니스 로직을 변경하지 않고, 로깅 로직을 Aspect로 분리하여 처리 할 수 있다.
@Aspect
@Component
public class LoggingAspect {
	
    @Around("execution(* com.example.service.*.*(..))")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        
        Object result = joinPoint.proceed();

        long end = System.currentTimeMillis();
        System.out.println("[실행 시간] " + joinPoint.getSignature() + " = " + (end - start) + "ms");
        
        return result;
    }
}
  1. 트랜젝션 처리
    Spring에서는 @Transactional 어노테이션을 사용해 AOP 방식으로 트랜잭션을 처리한다.
    이 어노테이션이 붙은 메서드는 내부적으로 AOP 프록시를 통해 트랜잭션의 시작, 커밋, 롤백 등을 처리한다.
@Transactional
public void transfer(String fromAccount, String toAccount, int amount) {
    // 송금 처리
}

Q. Spring MVC에서 클라이언트의 요청 처리 흐름을 @Controller와 @RestController의 차이점을 중심으로 각각의 처리 과정과 특징을 포함하여 설명하세오.

✅ @Controller

@Controller는 Spring MVC에서 클라이언트의 요청을 받아 처리하고 View를 반환하기 위한 클래스에 사용하는 어노테이션이다.

  • 반환 값은 View 이름으로 간주되고, ViewResolver가 해당 View를 찾아 렌더링한다.
  • 데이터를 직접 반환하기 위해서는 @ResponseBody 을 함께 활용해주어야 한다.
@Controller
public class UserController {

    @GetMapping("/user/view")
    public String userPage(Model model) {
        model.addAttribute("username", "홍길동");
        return "userView";	// templates/userView.html 랜더링
    }
}

✅ @RestController

@RestController@Controller@ResponseBody가 결합된 복합 어노테이션이다.
메서드의 반환 값을 View가 아닌 HTTP 응답 본문으로 직접 반환한다.

  • JSON 또는 XML 형식의 데이터를 응답으로 제공하며, 주로 REST API 개발에 활용된다.
@RestController
public class UserController {

    @GetMapping("/api/user")
    public UserDTO getUser() {
        return new UserDTO("홍길동", 30); // JSON {"name": "홍길동", "age": 30}
    }
}

⚙️ 클라이언트의 요청 처리 과정

클라이언트의 요청을 수신하고, 해당 요청과 메서드를 매핑하는 과정까지는 동일하나, 각 어노테이션에 따라 응답 처리 방식에 차이가 있다.

이미지 출처 : A Quick Introduction to Spring MVC

  • @Controller
  1. 비지니스 로직을 처리하고, 처리 결과를 Model 객체에 저장한다.
  2. View 이름(String)을 반환하며, 이 View 이름은 ViewResolver에 의해 실제 뷰 파일 경로로 변환된다.
  3. ViewResolver가 해당 뷰를 랜더링하고, 최종적으로 HTML 페이지가 클라이언트에게 전송된다.

만약, @ResponseBody가 함께 사용된 경우, 메서드의 반환값이 HTTP 응답 본문에 그대로 출력된다.

  • @RestController
  1. 비지니스 로직을 처리하고, 데이터 객체를 반환한다.
  2. 반환된 객체는 Spring의 HttpMessageConverter에 의해 JSON 또는 XML 형태로 자동 변환된다.
  3. 변환된 데이터가 HTTP 응답 본문에 담겨 클라이언트에게 전송된다.

📃 참고 문서

profile
개발자로 성장하기

0개의 댓글