[Spring] Filter / Interceptor / AOP 차이와 예시

allnight5·2023년 3월 30일
0

기술공부

목록 보기
9/33

목차
0. 공통 프로세스
0-1.Dispatcher-Servlet(디스패처 서블릿) 이란?
1. Filter 란 무엇인가?
2. Filter의 예시
2-1. Filter의 장점
2-2. Filter의 단점
3. Interceptor 란 무엇인가?
4. Interceptor 예시
4-1. Interceptor 장점
4-2. Interceptor 단점
5. AOP 란 무엇인가?
6. AOP 예시
6-1. AOP 장점
6-2. AOP 단점
7. Filter / Interceptor / AOP 차이

공통 프로세스


자바 웹 개발을 하다보면, 공통적으로 처리해야 할 업무들이 많다.

예를들어 로그인 관련(세션체크)처리, 권한체크, XSS(Cross site script)방어, pc와 모바일웹의 분기처리, 로그, 페이지 인코딩 변환 등이 있다.

공통업무에 관련된 코드를 모든 페이지 마다 작성 해야한다면 중복된 코드가 많아지게 되고 프로젝트 단위가 커질수록 서버에 부하를 줄 수도있으며, 소스 관리도 되지 않는다.

즉, 공통 부분은 빼서 따로 관리하는게 좋다.

이러한 공통업무를 프로그램 흐름의 앞, 중간, 뒤에 추가하여 자동으로 처리할 수 있는 방법이 있고 관련된 내용을 포스팅 하려고 한다.

· 공통 프로세스의 장점

1. 각 문제에 대한 논리가 소스코드 전체에 흩어져 있는 대신 한 곳에 존재한다.
2. 비즈니스 모듈에는 주요 관심사에 대한 코드만 포함된다.
3. 비즈니스 코드를 수정하지 않고도 추가 동작을 더할 수 있음

위와 같은 공통처리를 위해 활용할 수 있는 것이 3가지가 있다.

  1. Filter

  2. Interceptor

  3. AOP

공통프로세스들을 횡단 관심사 분리가 가능한것이다.

Filter, Interceptor, AOP의 흐름

Interceptor와 Filter는 Servlet 단위에서 실행된다. 반면 AOP는 메소드 앞에 Proxy패턴의 형태로 실행된다.

요청이 들어올때 아래와 같은 순서대로 처리된다.

servlet Request → Filter → DispatcherServlet
→ Interceptor → AOP → Controller → AOP 
→ Interceptor → DispatcherServlet → Filter 
→ servlet Request

0-1. Dispatcher-Servlet(디스패처 서블릿) 이란?

목차로 이동
HTTP 프로토콜로 들어오는 모든 요청을 가장 먼저 받아 적합한 컨트롤러에 위임해주는 프론트 컨트롤러(Front Controller)라고 정의할 수 있습니다.

이 모든 요청을 프론트 컨트롤러인 디스패처 서블릿이 가장 먼저 받게 됩니다. 그러면 디스패처 서블릿은 공통적인 작업을 먼저 처리한 후에 해당 요청을 처리해야 하는 컨트롤러를 찾아서 작업을 위임합니다.

MVC 구조에서 함께 사용되는 디자인 패턴입니다.

[ Dispatcher-Servlet(디스패처 서블릿)의 장점 ]

dispatcher-servlet이 해당 어플리케이션으로 들어오는 모든 요청을 핸들링해주고 공통 작업을 처리면서 상당히 편리하게 이용할 수 있게 되었습니다. 우리는 컨트롤러를 구현해두기만 하면 디스패처 서블릿가 알아서 적합한 컨트롤러로 위임을 해주는 구조가 되었습니다.

[ 정적 자원(Static Resources)의 처리 ]

모든 요청을 처리하다보니 이미지나 HTML/CSS/JavaScript 등과 같은 정적 파일에 대한 요청마저 모두 가로채는 까닭에 정적자원(Static Resources)을 불러오지 못하는 상황도 발생하곤 했습니다. 이러한 문제를 해결하기 위해 개발자들은 2가지 방법을 고안했습니다.

    1. 정적 자원 요청과 애플리케이션 요청을 분리
    1. 애플리케이션 요청을 탐색하고 없으면 정적 자원 요청으로 처리

1. 정적 자원 요청과 애플리케이션 요청을 분리

이에 대한 해결책은 두가지가 있는데 첫번째는 클라이언트의 요청을 2가지로 분리하여 구분하는 것입니다.

/apps 의 URL로 접근하면 Dispatcher Servlet이 담당한다.
/resources 의 URL로 접근하면 Dispatcher Servlet이 컨트롤할 수 없으므로 담당하지 않는다.

  • 이러한 방식은 괜찮지만 상당히 코드가 지저분해지며, 모든 요청에 대해서 저런 URL을 붙여주어야 하므로 직관적인 설계가 될 수 없습니다. 그래서 이러한 방법의 한계를 느끼고 다음의 방법으로 처리를 하게 되었습니다.

2. 애플리케이션 요청을 탐색하고 없으면 정적 자원 요청으로 처리

  • 두번째 방법은 Dispatcher Servlet이 요청을 처리할 컨트롤러를 먼저 찾고, 요청에 대한 컨트롤러를 찾을 수 없는 경우에, 2차적으로 설정된 자원(Resource) 경로를 탐색하여 자원을 탐색하는 것입니다.

이렇게 영역을 분리하면 효율적인 리소스 관리를 지원할 뿐 아니라 추후에 확장을 용이하게 해준다는 장점이 있습니다.


1.클라이언트의 요청을 디스패처 서블릿이 받음
2.요청 정보를 통해 요청을 위임할 컨트롤러를 찾음
3.요청을 컨트롤러로 위임할 핸들러 어댑터를 찾아서 전달함
4.핸들러 어댑터가 컨트롤러로 요청을 위임함
5.비지니스 로직을 처리함
6.컨트롤러가 반환값을 반환함
7.핸들러 어댑터가 반환값을 처리함
8.서버의 응답을 클라이언트로 반환함

위 순서에 대한 자세한 설명

1.클라이언트의 요청을 디스패처 서블릿이 받음

  • 서블릿 컨텍스트(웹 컨텍스트)에서 필터들을 지나 스프링 컨텍스트에서 디스패처 서블릿이 가장 먼저 요청을 받게됩니다.

2.요청 정보를 통해 요청을 위임할 컨트롤러를 찾음

  • 오늘날에는 주로 @Controller와 @RequestMapping 관련 어노테이션을 조합하여 컨트롤러를 생성하므로, 요청을 처리할 컨트롤러는 주로 HandlerMapping의 구현체 중 하나인 RequestMappingHandlerMapping가 찾아줍니다.

  • 찾아온 HandlerMethod를 andlerMethodExecutionChain으로 감싸서 반환화는데, 그 이유는 컨트롤러로 요청을 넘겨주기 전에 처리해야 하는 인터셉터 등을 포함하기 위해서입니다.

3.요청을 컨트롤러로 위임할 핸들러 어댑터를 찾아서 전달함

  • 다양하게 작성되는 컨트롤러에 대응하기 위해 스프링은 HandlerAdapter라는 어댑터 인터페이스를 통해 어댑터 패턴을 적용함으로써 컨트롤러의 구현 방식에 상관없이 요청을 위임할 수 있도록 하였습니다.

4.핸들러 어댑터가 컨트롤러로 요청을 위임함

  • 핸들러 어댑터가 컨트롤러로 요청을 넘기기 전에 공통적인 전처리 과정이 필요합니다.
  • 요청에 매칭되는 인터셉터들도 실행을 시키고, @RequestParam, @RequestBody 등으로 파라미터를 준비하는 ArgumentResolver도 실행하는 등의 다양한 공통 작업들이 수행됩니다.
  • 이러한 전처리 작업들이 완료되면 파라미터 값들과 함께 컨트롤러로 요청을 위임합니다.

5.비지니스 로직을 처리함

  • 컨트롤러는 서비스를 호출하고 우리가 작성한 비지니스 로직들이 진행됩니다.

6.컨트롤러가 반환값을 반환함

  • 비지니스 로직이 처리된 후에는 컨트롤러가 반환값을 반환합니다.
  • 응답 데이터를 사용하는 경우에는 주로 ResponseEntity를 반환하게 되고, 응답 페이지를 보여주는 경우라면 String으로 View의 이름을 반환할 수도 있습니다

7.핸들러 어댑터가 반환값을 처리함

  • 핸들러 어댑터는 컨트롤러로부터 받은 반환값을 응답 처리기인 ReturnValueHandler가 후처리한 후에 디스패처 서블릿으로 돌려줍니다

8.서버의 응답을 클라이언트로 반환함

  • 디스패처 서블릿을 통해 반환되는 응답은 다시 필터들을 거쳐 클라이언트에게 반환됩니다. 이때 응답이 데이터라면 그대로 반환되지만, 응답이 화면이라면 View의 이름에 맞는 View를 찾아서 반환해주는 ViewResolver가 적절한 화면을 내려줍니다.

1. Filter 란 무엇인가?

목차로 이동

  • Filter(필터)는 요청과 응답을 거른 뒤 정제하는 역할을 한다.

서블릿 필터는 DispatcherServlet 이전에 실행이 되는데 필터가 동작하도록 지정된 자원의 앞단에서 요청이나 리소스의 응답 또는 둘 다에 대해 필터링 작업을 수행하는 객체하고 할 수 있다.

자바 서블릿에서 제공하는 인터페이스 이다.

또한 자원의 처리가 끝난 후 응답 내용에 대해서도 변경하는 처리를 할 수가 있다.
보통 web.xml에 등록하고, 일반적으로 인코딩 변환 처리, XSS 방어 등의 요청에 대한 처리로 사용된다.

요즘에는 스프링에서는 web.xml이 아닌 build.gradle에 등록하여 처리하며 implements WebMvcConfigurer라는 인터페이스를 상속받고 구현체를 생성하여 필터 에서 검증하여 처리하기도 합니다.

필터를 추가하기 위해서는 javax.servlet의 Filter 인터페이스를 구현(implements)해야 하며 이는 다음의 3가지 메소드를 가지고 있다.

init(): 필터 인스턴스 초기화/ 서블릿 컨테이너 생성시 1회 호출
doFilter(): 전/후 처리
destroy(): 필터 인스턴스 종료/ 서블릿 컨테이너 종료시 1회 호출


웹 컨테이너(서블릿 컨테이너)에 의해 관리 되며 디스페쳐 서블릿이 동작하기 전에 동작한다.

2. Filter의 예시

목차로 이동

public interface Filter {

    public default void init(FilterConfig filterConfig) throws ServletException {
    	log.info("logfilter:init()");
    }

    public void doFilter(
            ServletRequest request, 
            ServletResponse response,
            FilterChain chain) throws IOException, ServletException{
            HttpServletRequest httpServletRequest = (HttpServletRequest)request;
            
            String requestURL = httpServletRequest.getRequestUrl();
            
            try{
    			log.info("logfilter: dofilter() = [>>>Request] {}", requestURL);
                chain.dofilter(request, response); // 다음 필터 호출(체이닝)
            }catch(Exception e){
            	throw e;
            }finally{
    			log.info("logfilter: dofilter() = [<<<Reseponse] {}", requestURL);
            }
    }

    public default void destroy() {
    	log.info("logfilter:distroy()");
    }
}

init 메소드

init 메소드는 필터 객체를 초기화하고 서비스에 추가하기 위한 메소드이다.
웹 컨테이너가 1회 init 메소드를 호출하여 필터 객체를 초기화하면 이후의 요청들은 doFilter를 통해 처리된다.

doFilter 메소드

doFilter 메소드는 url-pattern에 맞는 모든 HTTP 요청이 디스패처 서블릿으로 전달되기 전에 웹 컨테이너에 의해 실행되는 메소드이다.
doFilter의 파라미터로는 FilterChain이 있는데, FilterChain의 doFilter 통해 다음 대상으로 요청을 전달하게 된다.
chain.doFilter() 전/후에 우리가 필요한 처리 과정을 넣어줌으로써 원하는 처리를 진행할 수 있다.

destroy 메소드

destroy 메소드는 필터 객체를 서비스에서 제거하고 사용하는 자원을 반환하기 위한 메소드이다.
이는 웹 컨테이너에 의해 1번 호출되며 이후에는 이제 doFilter에 의해 처리되지 않는다.

2-1. Filter의 장점


들어오는 request와 response 객체를 변경하여 처리할수있다.

2-2. Filter의 단점


스프링 내에서의 예외처리가 되지않아 따로 작성해주어야한다.
필터를 타고 이동하는데 추가 작업이 필요로 한다.

3. Interceptor 란 무엇인가?

목차로 이동


Spring이 제공하는 기술로써, 디스패처 서블릿(Dispatcher Servlet)이 컨트롤러를 호출하기 전과 후에 요청과 응답을 참조하거나 가공할 수 있는 기능을 제공한다.
즉, 웹 컨테이너(서블릿 컨테이너)에서 동작하는 필터와 달리 인터셉터는 스프링 컨텍스트에서 동작을 하는 것이다.

디스패처 서블릿은 핸들러 매핑을 통해 적절한 컨트롤러를 찾도록 요청하는데, 그 결과로 실행 체인(HandlerExecutionChain)을 돌려준다.

이 실행 체인이 인터셉터가 등록되어있다면 순차적으로 인터셉터들을 거쳐 컨트롤러가 실행되도록 하며, 없다면 바로 컨트롤러를 실행하게 된다.

인터페이스도 필더와 마찬하지로 인터페이스를 구현(implements)해야 하며 다음의 3가지 메소드를 가지고 있다.

preHandle() : 컨트롤러가 호출되기 전에 실행(전처리 작업, 요청 정보 조작 등)
postHandle() : 컨트롤러가 호출된 후에 실행(후처리 작업, 요청 정보 조작 등)/ 컨트롤러(서비스, 저장소(Repositoty)) 하위 계층에서 예외 발생시 실행하지 않습니다.
afterCompletion() : 요청 완료후 실행/ 컨트롤러 하위 계층(서비스, 저장소(Repositoty))예외가 발생하더라도 반드시 실행


4. Interceptor 예시

목차로 이동

Config 부분

@Configuration
public class WebConfig implements WEbMvcConfigurer{
	@Override
    public void addInterceptors(InterceptorRegistry registry){
    	registry.addInterceptor(new LogInterceptor())
        	.order(1)
        	.addPathPatterns("/api/**");
            /* addPathPatterns로 Interceptors할URL을 지정해준다면
            /api/user 혹은 /api/member와 
            같이 api 다음에 내용이 있는 Url요청에서
            인터셉터가 필터를 거쳐왔을때 낚아 채서 실행되게 됩니다.
            */
    }
}

사용부분

public interface HandlerInterceptor {

    default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
        throws Exception {
        log.info("LogInterceptor : preHandle()");
        return true; // filter와 같은데 true주면 다음것을 호출하고 false라면 다음것을 호출하지 않습니다.
    }

    default void postHandle(HttpServletRequest request, 
        HttpServletResponse response, 
        Object handler,
        @Nullable ModelAndView modelAndView) throws Exception {
        log.info("LogInterceptor : postHandle()");
    }

    default void afterCompletion(HttpServletRequest request, 
        HttpServletResponse response, 
        Object handler,
        @Nullable Exception ex) throws Exception {
        log.info("LogInterceptor : afterCompletion()");
    }
}

preHandle 메소드

preHandle 메소드는 컨트롤러가 호출되기 전에 실행된다. 그렇기 때문에 컨트롤러 이전에 처리해야 하는 전처리 작업이나 요청 정보를 가공하거나 추가하는 경우에 사용할 수 있다.

preHandle의 3번째 파라미터인 handler 파라미터는 핸들러 매핑이 찾아준 컨트롤러 빈에 매핑되는 HandlerMethod라는 새로운 타입의 객체로써, @RequestMapping이 붙은 메소드의 정보를 추상화한 객체이다.

또한 preHandle의 반환 타입은 boolean인데 반환값이 true이면 다음 단계로 진행이 되지만, false라면 작업을 중단하여 이후의 작업(다음 인터셉터 또는 컨트롤러)은 진행되지 않는다.

postHandle 메소드

postHandle 메소드는 컨트롤러를 호출된 후에 실행된다. 그렇기 때문에 컨트롤러 이후에 처리해야 하는 후처리 작업이 있을 때 사용할 수 있다.
이 메소드에는 컨트롤러가 반환하는 ModelAndView 타입의 정보가 제공되는데, 최근에는 Json 형태로 데이터를 제공하는 RestAPI 기반의 컨트롤러(@RestController)를 만들면서 자주 사용되지는 않는다.

또한 컨트롤러 하위 계층에서 작업을 진행하다가 중간에 예외가 발생하면 postHandle은 호출되지 않는다.

afterCompletion 메소드

afterCompletion 메소드는 이름 그대로 모든 뷰에서 최종 결과를 생성하는 일을 포함해 모든 작업이 완료된 후에 실행된다.
요청 처리 중에 사용한 리소스를 반환할 때 사용하기에 적합하다.
postHandler과 달리 컨트롤러 하위 계층에서 작업을 진행하다가 중간에 예외가 발생하더라도 afterCompletion은 반드시 호출된다.

4-1. Interceptor 장점

좀더 세분화된 시점에서 처리할수있다.
다음 인터셉터로 넘어가는데 별다른 처리가 필요없다.

4-2. Interceptor 단점

request, response 객체를 변경할 수 없다.

Filter Vs Intercepter 차이

목차로 이동

필터의 경우

  • 공통된 인증/인가
  • 모든 요청에 대한 로깅 또는 감사
  • 이미지/데이터 압축 문자열 코딩
  • 스프링과 무관하게 전역적으로 처리할 작업

인터셉터

  • 세부적인 인증/인가
  • API호출에 대한 로깅
  • 컨트롤러로 넘겨주는 정보의 가공이 필요할때

차이점

인터셉터가 손이 덜간다

그이유는

  • 필터의 경우 다음 필터를 실행하기 위해 직접 코드를 작성해야 하지만
  • 인터셉터의 경우 return true 라고 해주면 된다

필터는 request,response 객체를 변경할 수 있지만, 인터셉터는 그렇지 않다.

필터는 request,response를 다른 객채로 바꿔치기하여 다음 필터로 전달이 가능하다

HttpServletRequest httpServletRequest = (HttpServletRequest)request;
chain.dofilter(request, response);

하지만 인터셉터의 경우 바꾸지 못하고 그냥 인터셉터 내용만 실행하고 넘어가게된다
request,response를 다른 객채로 변경하여 다음 인터셉터로 넘겨줄 수 없다.

return true

위의 내용이 전부기 때문이다.

필터가 인터셉터보다 강한것이 이런 이유가 있다.

스프링의 예외처리

필터의 경우

  • 스프링의 예외처리가 불가능하다

인터셉터의 경우

  • 스프링의 예외처리가 가능하다

우리는 어떤 것을 쓰는것이 좋은가?

우리는 스프링을 이용해 로직을 처리한다.

서블릿 필터는 단순히 doFilter()하나만 제공하지만

인터셉터는 단계적으로 세분화 되어있다.

preHandle() : 컨트롤러가 호출되기 전
postHandle() : 컨트롤러가 호출된 후
afterCompletion() : 요청 완료 후

5. AOP 란 무엇인가?

목차로 이동

AOP는 OOP를 보완하기 위해 나온 개념이다. 객체 지향의 프로그래밍을 했을 때 중복을 줄일 수 없는 부분을 줄이기 위해 종단면(관점)에서 바라보고 처리한다.

AOP는 공통된 기능을 재사용하는 기법 입니다.
OOP에선 공통된 기능을 재사용하는 방법으로 상속이나 위임을 사용합니다.

주로 ‘로깅’, ‘트랜잭션’, ‘에러 처리’ 등 비즈니스단의 메소드에서 조금 더 세밀하게 조정할 때 사용한다.

Interceptor나 Filter와는 달리 메소드 전후의 지점에 자유롭게 설정이 가능하다. Interceptor와 Filter는 주소로 대상을 구분해서 걸러내야 하는 반면, AOP는 주소, 파라미터, 애노테이션 등 다양한 방법으로 대상을 지정할 수 있다.

AOP의 Advice와 HandlerInterceptor의 가장 큰 차이는 파라미터의 차이다. Advice의 경우 JoinPoint나 ProceedingJoinPoint 등을 활용해서 호출한다. 반면 HandlerInterceptor는 Filter와 유사하게 HttpServletRequest, HttpServletResponse를 파라미터로 사용한다.

@Aspect : 애너테이션이 달린 일반 클래스를 사용하여 aspect를 구현할 수 있다.

  • 횡단 관심사의 동작과 그 횡단 관심사를 적용하는 소스 코드상의 포인트를 모은 것이다.
  • 즉, 하나 이상의 어드바이스(동작)와 포인트컷(동작을 적용하는 조건)을 조합한 것이다.

조인포인트(Joinpoint): 어드바이스가 실행하는 동작을 끼워 넣을 수 있는 때를 말한다.

  • 조인 포인트는 개발자가 고려해서 만들어 넣을 수 없는 AOP(제품)의 사양이다. 스프링에서는 메서드가 호출될 때와
  • 메서드가 원래 호출한 곳으로 돌아갈 떄가 어드바이스를 끼워 넣을 수 있는 조인 포인트다.

어드바이스(Advice): 조인 포인트에서 실행되는 코드를 말한다. 로그 출력, 트랜잭션 관리 등의 코드가 기술된다.

포인트컷(Pointcut): 어드바이스가 실행되는 하나 이상의 조인 포인트를 선택하는 표현식이다.

  • 표현식이나 패턴을 사용하여 포인트컷을 정의할 수 있다. 조인 포인트와 매칭되는 다양한 종류의 표현식을 사용할 수 있으며,
  • 스프링 프레임워크는 AspectJ pointcut 표현 언어를 사용한다.

@Before: 대상 메소드의 수행 전

@After: 대상 메소드의 수행 후

@After-returning: 대상 메소드의 정상적인 수행 후

@After-throwing: 예외발생 후

@Around: 대상 메소드의 수행 전, 후 (Before와 After을 합친것이다)

AOP VS OOP

AOPOOP
Aspect: 포인트컷, 어드바이스 및 속성을 캡슐화하는 코드 단위Class: 메서드와 속성을 캡슐화하는 코드 단위
Pointcut: 어드바이스가 실행되는 진입점들을 정의Method Signature: 메서드 바디 실행을 위한 진입점들을 정의
Advice: 횡단 관심사의 구현Methid bodies: 비즈니스 로직 관심사의 구현
Weaver: 어드바이스로 코드(소스 또는 개체)를 구성함Compier: 소스 코드를 객체 코드르 변경함

6. AOP 예시

목차로 이동


@Aspect
@Component
public class aopExample{

    @Pointcut("within(*..*Controller)")
    private void cut(){}


    // 조인포인트를 어노테이션으로 설정
    @Pointcut("@annotation(com.team.final8teamproject.aop.Timer)")
    private void timer(){}


    @After("cut()")
    public void AfterAOP(){
        log.info("AOP : AfterAOP");
    }

    @Before("cut()")
    public void beforeAOP(){
        log.info("AOP : BeforeAOP");
    }
    
    // 이런형식으로 해주려면
    // User라는 객체에 set과 get 생성자가 있거나
    //@Getter과 @Setter가 있어야한다.
   	// 다끝난다음에 케이스 변환을 시켜서 변경한 다음 리턴 값을 보내준다.
    @AfterReturning(value = "execution( * cut())", returning = "returnValue")
    public void AfterReturningAOP(JoinPoint joinPoint, List<User> returnValue) throws RuntimeException{
        log.info("Aspect(@AfterReturning) :: afterReturningFindAccountsAdvice is executed after "
                + joinPoint.getSignature().toShortString());
        log.info(returnValue.toString());

        returnValue = returnValue.stream().map(result-> {
            result.setUsername(result.getUsername().toUpperCase());
            return result;
        }).collect(Collectors.toList());
        //returnValue 는 해당 메서드의 리턴객체를 그대로 가져올 수 있다.
        log.info("AOP : AfterReturning");
    }
    
    @AfterThrowing(value = "execution(* com.team.test.user.controller.*(..))", throwing = "exception" )
    public void AfterThrowingAOP(JoinPoint joinPoint, Exception exception) throws RuntimeException{
        //exception 으로 해당 메서드에서 발생한 예외를 가져올 수 있다.
        log.info("AOP : AfterThrowingAOP, Throw = {}", exception.getMessage());
        throw new CustomException(ExceptionStatus.NOT_FOUNT_USER);
    }
    
    @Around("timer()")
    public Object AssumeExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {

        StopWatch stopWatch = new StopWatch();

        stopWatch.start();
        Object proceed = joinPoint.proceed();// 조인포인트의 메서드 실행
        stopWatch.stop();

        long totalTimeMillis = stopWatch.getTotalTimeMillis();

        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getMethod().getName();

        log.info("실행 메서드: {}, 실행시간 = {}ms", methodName, totalTimeMillis);
        return proceed;
    }
}  

6-1. AOP 장점

6-2. AOP 단점

7. Filter / Interceptor / AOP 차이

목차로 이동
1) 적용 시점이 다르다

  • Filter -> Intercepter -> AOP 의 순서대로 실행된다.
    - filter는 사용자의 request를 받아서 servlet에 가기 전에 실행된다.
    - interceptor는 controller에 가기 전에 실행된다.
    - aop는 어드바이스에 따라 비즈니스 메소드가 호출될 때, 호출된 후, 예외가 발생하는 시점등에서 적용된다.

2) 적용 방식이 다르다
스프링 3.x 이전

  • Filter: web.xml
  • Iterceptor: servlet-context.xml
  • AOP : XML 기반의 POJO 클래스를 이용한 AOP 구현 방식

스프링 3.x 이후

  • Filter : Java Config나 WebApplicationInitializer를 사용하여 등록합니다.
  • Iterceptor: Java Config (Spring Context에 등록되어야 합니다)
  • AOP : Java Config

3.X 이후로는 모두 java Config를 활용해서 등록이 가능하지만 등록되는 위치는 다르다.

3) 실행 위치가 다름

  • Interceptor, Filter: Servlet 단위에서 실행
  • AOP: 메소드 앞에 Proxy 패턴의 형태로 실행

4) 동작 기반이 다르다.
Filter : spring과 무관한 servlet의 기술, url 기반으로 동작한다.
Interceptor : spring의 기술, url 기반으로 동작, 빈 객체에 접근 가능하다.
AOP : spring의 기술, pointcut 기반으로 동작, 웹과 무관하게 business logic과 연결해서 사용됨, 빈 객체에 접근 가능하다.

참조사이트

Filter / Interceptor / AOP
goodorbad
AOP
망나니 개발자(Filter/Interceptior)
Filter/Interceptior 영상

profile
공부기록하기

0개의 댓글