이전 포스팅에서 스프링 프레임워크의 역할 중 AOP가 있다고 이야기한 바 있다.
AOP를 사용해서 얻는 이점 정도만 정리했을 뿐, AOP가 무엇이고 왜, 어떻게 사용되는지는 일절 설명하지 않았다.
하지만 이 AOP 또한 스프링 개발에서 매우 중요한 역할을 맡고 있다. 당연히 자주 쓰이기도 하고 말이다.
자주 쓰이지만 어떤건지, 어떻게 동작하는지 그 원리도 모르면서 관습적으로 사용하기보다, 확실히 이해하고 필요할 때 적재적소에 사용할 수 있어야 좋은 개발자가 될 수 있을 것이다.
그런 의미에서 이번엔 AOP를 비롯해, 스프링에서 그와 비슷한 역할을 하는 3가지 도구에 대해서 알아보고자 한다.
- 비즈니스 개발 외에도 공통적으로 처리하는 게 좋은 기능들이 많이 있음
- 로깅, 보안 등이 대표적인 예시
- 이러한 공통된 부분은 따로 분리하여 관리하는 것이 좋음
- 이러한 공통 업무를 프로그램 흐름에 따라, 단위별로 자동으로 처리할 수 있는 방법이 존재
Filter,Interceptor,AOP가 그 주인공

Filter 와 Interceptor 는 Servlet 단위에서 실행AOP 는 메서드 앞에 Proxy 로 감싸져 실행Filter -> Interceptor -> AOP 순서 및 역순으로 처리1) 애플리케이션이 실행되면 서블릿 컨테이너가 구동되며, DispatcherServlet을 초기화
web.xml or @Configuration ) 처리2) 클라이언트의 요청이 들어오면, Filter 의 doFilter 실행
3) 요청이 DispatcherServlet에 도달하면, preHandler가 실행
Interceptor 의 일부이며, HandlerInterceptor 인터페이스에 정의된 메서드Interceptor 내부에서 요청의 전처리 단계를 담당4) DispatcherServlet 은 요청을 컨트롤러 매핑 하여 적절한 HandlerAdapter 를 통해 컨트롤러 호출
5) 컨트롤러, 서비스 등 각 계층 전체에서, 비즈니스 로직과 관련된 각 메서드 실행 전후로 AOP 를 통한 작업 처리
6) 컨트롤러 실행 후, postHandler가 실행
Interceptor 의 일부이며, Interceptor 내부에서 요청의 후처리 단계를 담당7) 서블릿 종료 시 distroy 실행
1) 클라이언트가 서버에 HTTP 요청을 보냄
2) 서블릿 컨테이너가 요청을 처리하기 전에, 등록된 Filter Chain을 따라 Filter 실행
3) 요청은 각 Filter를 순차적으로 통과하고, 모두 통과하면 서블릿으로 전달됨
doFilter() 메서드가 호출되어 다음 필터 및 서블릿으로 요청 전달4) 서블릿에서 응답을 생성한 후, 응답은 다시 Filter Chain을 거쳐 클라이언트로 반환
@WebFilter("*")
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletExcepton {
System.out.println("요청 처리 전 Filter");
chain.doFilter(request, response) // 다음 필터 및 서블릿으로 요청 전달
System.out.println("요청 처리 후 Filter");
}
}
1) 요청은 서블릿에서 처리된 후 스프링 MVC로 전달됨
2) HandlerInterceptor 가 등록된 순서대로 실행
preHandle : 컨트롤러 호출 전 실행boolean 값에 따라 요청 전달 유무 판단postHandle : 컨트롤러가 요청을 처리하고 응답을 반환한 후 실행afterCompletion : 응답이 클라이언트로 반환되기 직전 실행public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("컨트롤러 호출 전 Interceptor");
return true;
}
@Override
public boolean postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("컨트롤러 호출 후 Interceptor");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception ex) throws Exception {
System.out.println("모두 완료");
}
}
1) 요청이 스프링 컨테이너에 도달
2) 스프링 컨텍스트에서 프록시 객체를 통해 대상 객체에 접근
3) 프록시 객체가 JoinPoint 를 가로채고 Advice 실행
Aspect 에 정의된 Advice 실행@Before : 메서드 호출 전 실행@After : 메서드 호출 후 실행@Around : 메서드 호출 전/후 모두 실행, 직접 실행하거나 실행을 건너뛸 수 있는 가장 강력한 Advice4) 대상 객체의 메서드를 호출한 후 반환값 처리
JoinPoint 의 proceed() 메서드를 통해 실제 메서드 호출5) 응답이 클라이언트로 전달
@Aspect
@Component
public class myAspect {
@Before("execution(* com.example.service.*.*(..))") // 타겟 메서드 실행 전 실행할 동작
public void logBefore(JoinPoint joinPoint) {
// 실행되는 메서드의 이름을 반환
System.out.println("AOP 메서드 호출 전 : " + joinPoint.getSignature().getName());
}
@After("execution(* com.example.service.*.*(..))") // 타겟 메서드 실행 후 실행할 동작
public void logAfter(JoinPoint joinPoint) {
System.out.println("AOP 메서드 호출 후 : " + joinPoint.getSignature().getName());
}
@Around("execution(* com.example.service.*.*(..))") // 타겟 메서드 전후로 실행
public Object logAround(ProceedingJoinPoint joinPoint) {
System.out.println("AOP 메서드 호출 전 : " + joinPoint.getSignature().getName());
Object result = joinPoint.proceed(); // 타겟 메서드 실행 결과 반환
System.out.println("AOP 메서드 호출 후 : " + joinPoint.getSignature().getName());
return result; // 호출한 곳으로 타겟 메서드의 결과를 반환
}
}
💡 포인트컷 execution(* com.example.service.*.*(..)) 해석
* 위치int , String , void ...)* 위치example.service 패키지 아래의 모든 클래스 대상* 위치(..).. 은 모든 타입과 개수 허용(String) : String 타입 하나의 파라미터를 받는 메서드만 매칭(*, int) : 두 개의 파라미터 중 첫 번째는 상관 없고, 두 번째는 int 타입인 메서드만 매칭logAround() 메서드 내에서 logBefore , logAfter 메서드와 동일한 역할을 수행하는 부분이 있는데, 그대로 사용해도 될까?@Before 와 @After 로 전/후 처리를 해뒀음logAround() 에서 이를 호출하면, 전/후 처리를 한 번씩 추가로 진행Advice 는 다른 Advice 를 신경쓰지 말고, 자신의 역할에만 충실| 특징 | Filter | Interceptor | AOP |
|---|---|---|---|
| 적용 범위 | 서블릿 수준 | 스프링 MVC 수준 | 스프링 컨테이너 전역 (핵심 로직) |
| 적용 시점 | 요청 전후 | 컨트롤러 전후 | 메서드 전후, 예외 처리, 객체 초기화 등 |
| 사용 목적 | 인증, 요청/응답 처리 | 인증, 데이터 가공, MVC 로직 처리 | 트랜잭션, 로깅, 공통 로직 처리 |
| 설정 방식 | 서블릿 컨테이너 설정 | WebMvcConfigurer 설정 | @Aspect 및 Pointcut 설정 |
참고) OpenAI. (2024).ChatGPT(4o)[Large language model].https://chatgpt.com/
https://goddaehee.tistory.com/154