# **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 애플리케이션을 더욱 강력하고 유지보수하기 쉽게 만들 수 있습니다!**