우리는 Spring Core에서 AOP에 대한 개념을 학습했었다.

 

2020/04/17 - [JAVA/Spring] - AOP

 

AOP

AOP이란? Aspect Oriented Programming : 관점 지향 프로그래밍 하나의 프로그램을 관점(관심사)라는 논리적인 단위로 분리하여 관리하는 개념이다. 여기에서 관심사란 메소드 호출이나 특정주소를 요청하는 등의..

programmingrecoding.tistory.com

Interceptor는 이러한 AOP의 개념을 적용한 Spring MVC의 요소라고 할 수 있다.

Interceptor는 요청 주소에 대해 관심을 갖고 요청이 발생하게 되면 요청 주소를 확인하여 Controller의 메소드를 호출하기 전이나 후에 다른 메소드를 호출 할 수 있도록 가로채가는 개념이다.

요청 발생 시 호출되는 메소드의 코드가 중복되는 부분이 있을 때 Interceptor를 통해 처리하게 된다.

 

이는 로그인 여부 확인, 등급별 서비스 사용 권한 확인 등의 작을 처리할 때 많이 사용된다.

 

 

Interceptor는 HandlerInterceptor인터페이스를 구현하거나 HandlerInterceptorAdapter를 상속받은 클래스를 만들고 다음 메소드를 구현한다.

HandlerInterceptor에는 디폴트 메소드로 메소드가 정의되어 있다. Spring 예전버전에서는 메소드가 모두 추상메소드여서 전부 구현클래스에서 오버라이딩하여 구현을 했어야 했으나, 디폴트 메소드로 되어있기때문에 필요한 메소드만 오버라이딩해서 사용하면 되겠다. 

 

HandlerInterface의 구조

 

대표적인 메소드 3개를 알아보자. 

 

preHandle 

Controller의 메소드가 호출되기 전에 호출이 된다. 이 메소드가 false를 반환하면 코드의 흐름이 중단된다. PreHandle 이후에 postHandle이나 afterComletion이 있어도 코드의 흐름은 중단된다. 그렇기 때문에 페이지도 다음으로 넘어가지지 않는다.

 

postHandle

Controller의 메소드가 수행이 완료된 후, View처리를 수행하기 전에 호출된다. 

 

afterCompletion

View처리까지 완료되고 응답결과가 브라우저로 전달되기 전에 호출된다.

 

 

 

 

위와 같이 HandlerInterface 인터페이스의 구현 클래스를 정의한 후에는 Interceptor를 등록해주어야 한다.

등록은 Java로 설정되어 있는 프로젝트와 Xml로 설정되어 있는 프로젝트의 셋팅방법이 다르다. 

 

 

ServletAppContext.java

 

Spring 설정파일에 다음과 같이 addInterceptor라는 메소드를 오버라이딩 해줌으로서 Interceptor를 등록할 수 있다. 이 메소드는 WebMvcConfigurer 인터페이스의 default 메소드이기 때문에 선택적으로 오버라이딩하여 사용할 수 있다.

 

아까 정의하였던 HandlerInterceptor구현클래스의 객체를 만들고 InterceptorRegistration형의 변수에 addInterceptor메소드를 활용하여 객체를 매개변수로서 삽입해준다. 그 후 그 변수에 addPathPetterns메소드를 사용하여 요청 경로를 넣어준다. 여기에 등록된 요청주소와 일치하는 주소가 요청되면 Interceptor로 등록된 구현 클래스의 메소드에 따라서 preHandle이나 postHadle이나 afterCompletion이 위치에 맞게 호출되게 된다. 

Controller로 바로 가는게 아니라 Interceptor에 있는 메소드를 실행하는 것이다.

 

 

 

Servlet-Context.xml

 

xml파일에서 interceptor를 등록하는 방법이다.

HandlerInterceptor를 구현한 클래스를 빈으로 등록한 후, 그 빈을 <interceptor>태그안의 <beans:ref>태그를 이용해서 주입해준다. interceptor가 여러개라면 <interceptors>태그안에 여러개의 <interceptor>를 등록해주면 되겠다.

 

 

 

 

 

위의 예제를 실행해보면, 

 

실행결과

 

이렇게 정상적으로 메소드의 순서를 가로채서 호출이 완료된다.

Interceptor는 코드의 흐름을 잘 알 필요가 있다.. 헷갈린다. 

만약 Interceptor가 2개이면 perHanlde은 위에서 아래 방향으로 코드가 실행되지만 PostHandel과 afterCompletion은 아래에서 위로 실행된다. 

 

 

 

TestInterceptor1과 똑같이 preHadle, postHandle, afterCompletion이 있는 TestInterceptor2를 만들어서 interceptor2로 등록을 해준 후 실행을 해보았다.

 

 

 

실행결과

 

실행결과를 보면 preHandle은 위에서 아래로 순서대로 TestInterceptor1, TestInterceptor2가 실행되었지만 postHandle과 afterCompletion은 아래에서 위로 코드가 진행되어 TestInterceptor2가 TestInterceptor1보다 먼저 실행되는 결과를 볼 수 있었다.

 

 

 

자바이든 xml이든 interceptor가 요청되야 할 Path를 지정해주었었다. 매번 요청주소값을 정확히 할 수 없을 뿐더러 하위주소가 여래개 있을 때에는 패턴을 이용해서 등록해주는 것이 좋다.

 

 

Pattern

* : 이름 하나를 의미하며 글자수, 글자등 제한x
   -> /a/* 하면 a까진 똑같고 *에는 아무거나

? : 글자하나를 의미
** : 하위 이름까지 포함하여 글자수, 글자 제한x
   -> /k, /a/b, /b/B  : /** 저거 다 포함 
   -> /** 하면 뒤에 몇덩어리가 나와도 상관 x, 그냥 / 에도 반응한다.

excludePathPatterns("/*"); 하면 덩어리 한개만있는거는 관심사에서 제외하겠다는 의미이다.

'JAVA > Spring MVC' 카테고리의 다른 글

RestController  (0) 2020.05.04
예외처리  (0) 2020.05.03
JSR-303, JSR-380 어노테이션  (0) 2020.05.01
에러메세지 커스터마이징  (2) 2020.04.30
Spring MVC 유효성검사  (0) 2020.04.30

+ Recent posts