2025-04-08T19:56:24

This commit is contained in:
2025-04-08 19:56:24 +09:00
parent a75a1dbd0f
commit eef061c1c9
100 changed files with 18639 additions and 0 deletions

View File

@@ -0,0 +1,184 @@
# **Spring Boot 요청 처리 고급 기능: 필터, 인터셉터, AOP 활용**
Spring Boot에서 클라이언트의 **요청을 처리하는 과정**은 단순히 컨트롤러에서 요청을 받고 응답을 반환하는 것 이상으로 확장될 수 있습니다.
특히 **보안, 로깅, 성능 모니터링, 인증/인가**와 같은 공통 기능을 처리하려면 **필터(Filter), 인터셉터(Interceptor), AOP(Aspect-Oriented Programming)** 등의 개념을 활용할 필요가 있습니다.
이번 글에서는 **필터, 인터셉터, AOP**를 활용하여 **요청을 가로채고, 원하는 로직을 추가하는 방법**을 실무 예제와 함께 설명하겠습니다.
---
# **1. 필터(Filter) - 요청 전/후 공통 처리**
### **📌 필터란?**
필터는 **서블릿 수준에서 동작하며, 요청이 컨트롤러에 도달하기 전/후에 특정 로직을 실행**할 수 있는 기능입니다.
Spring Boot에서는 `javax.servlet.Filter` 인터페이스를 구현하여 커스텀 필터를 만들 수 있습니다.
### **📌 필터의 주요 활용 사례**
- **CORS 처리**
- **요청 및 응답 로깅**
- **JWT 인증 처리**
- **IP 차단 등 보안 정책 적용**
### **📌 필터 구현 예제 - 요청 로깅**
아래는 **모든 요청의 URL과 실행 시간을 기록하는 필터**입니다.
```java
import jakarta.servlet.*;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component;
import java.io.IOException;
@Component // 자동으로 필터 등록
public class LoggingFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
long startTime = System.currentTimeMillis();
System.out.println("[LoggingFilter] 요청 URI: " + req.getRequestURI());
chain.doFilter(request, response); // 요청을 다음 필터 또는 컨트롤러로 전달
long duration = System.currentTimeMillis() - startTime;
System.out.println("[LoggingFilter] 요청 처리 시간: " + duration + "ms");
}
}
```
`doFilter()` 메서드는 **요청을 가로채서 원하는 작업을 수행한 후, 체인(chain)으로 넘겨줌**
✔ 요청 전후로 실행할 로직을 자유롭게 추가 가능
---
# **2. 인터셉터(Interceptor) - 요청 흐름을 제어**
### **📌 인터셉터란?**
인터셉터는 **Spring MVC에서 동작하며, 컨트롤러 실행 전후에 특정 로직을 추가할 수 있는 기능**입니다.
필터보다 **더 세부적인 요청 흐름을 제어**할 수 있으며, **특정 컨트롤러 또는 요청 경로에만 적용 가능**합니다.
### **📌 인터셉터의 주요 활용 사례**
- **사용자 인증 및 권한 체크**
- **API 요청 제한 (Rate Limiting)**
- **로그 및 성능 모니터링**
- **특정 요청의 파라미터 검사**
### **📌 인터셉터 구현 예제 - 인증 체크**
아래는 **특정 API에 접근할 때, 인증된 사용자만 허용하는 인터셉터**입니다.
```java
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.stereotype.Component;
@Component
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
String authHeader = request.getHeader("Authorization");
if (authHeader == null || !authHeader.startsWith("Bearer ")) {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.getWriter().write("Unauthorized");
return false; // 요청을 차단
}
// JWT 검증 로직 추가 가능 (예: Token 검증)
System.out.println("[AuthInterceptor] 인증 성공");
return true; // 요청 진행 허용
}
}
```
`preHandle()` 메서드는 **컨트롤러 실행 전에 요청을 가로채서 검사 가능**
✔ 인증이 실패하면 `false`를 반환하여 **요청을 차단할 수 있음**
### **📌 인터셉터 등록 (WebMvcConfigurer)**
인터셉터를 사용하려면 **WebMvcConfigurer**에 등록해야 합니다.
```java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private AuthInterceptor authInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authInterceptor)
.addPathPatterns("/api/**") // 특정 URL에만 적용
.excludePathPatterns("/api/public/**"); // 예외 URL 설정
}
}
```
---
# **3. AOP (Aspect-Oriented Programming) - 횡단 관심사 처리**
### **📌 AOP란?**
AOP는 **비즈니스 로직과는 별개로 공통 기능(로깅, 트랜잭션, 보안 등)을 적용하는 프로그래밍 기법**입니다.
Spring Boot에서는 `@Aspect``@Around`를 활용하여 **메서드 실행 전후에 특정 로직을 추가**할 수 있습니다.
### **📌 AOP의 주요 활용 사례**
- **로깅(Log Tracing)**
- **트랜잭션 관리**
- **메서드 실행 시간 측정**
- **입출력 값 검증**
### **📌 AOP 구현 예제 - 로깅 및 실행 시간 측정**
아래는 **모든 서비스 메서드의 실행 시간을 로깅하는 AOP**입니다.
```java
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@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 duration = System.currentTimeMillis() - start;
System.out.println("[AOP] " + joinPoint.getSignature() + " 실행 시간: " + duration + "ms");
return result;
}
}
```
`@Aspect` 선언으로 AOP 활성화
`@Around("execution(* com.example.service.*.*(..))")`**특정 패키지의 모든 메서드에 적용 가능**
`joinPoint.proceed()`를 호출하여 **실제 메서드를 실행하고, 이후 로직을 추가할 수 있음**
---
# **4. 필터, 인터셉터, AOP 비교**
| 기능 | 동작 위치 | 주요 목적 | 적용 대상 | 실행 시점 |
|------|---------|---------|---------|---------|
| **Filter** | 서블릿 레벨 | 요청 전처리 및 후처리 (보안, 로깅) | 모든 요청 | 컨트롤러 실행 전후 |
| **Interceptor** | Spring MVC 레벨 | 인증, 권한 체크 | 특정 요청 (API) | 컨트롤러 실행 전후 |
| **AOP** | 메서드 레벨 | 로깅, 트랜잭션, 성능 측정 | 특정 패키지/클래스의 메서드 | 메서드 실행 전후 |
---
# **5. 정리**
**필터(Filter)**: **모든 요청에 대해 전역적인 로직 적용 (보안, CORS, 로깅)**
**인터셉터(Interceptor)**: **컨트롤러 실행 전후에 특정 요청을 가로채서 인증/인가 처리**
**AOP(Aspect-Oriented Programming)**: **특정 메서드(비즈니스 로직)의 실행 전후에 로직 추가 (로깅, 성능 측정 등)**
이러한 고급 기능을 활용하면 **Spring Boot 애플리케이션을 더욱 강력하고 유지보수하기 쉽게 만들 수 있습니다!**