-- INDEX --
1~2 : DelegatingFilterproxy | 3. Proxy | 4~8 : Interceptor |
사용법 및 실습 질문답변타임 |
특징 및 작동원리 | 정의 및 실습 메서드 사용이유 정리 |
1. DelegatingFilterproxy
- 스프링에서 관리하는 필터를 만들어보자
- 스프링이 관리하는 필터 클래스를 이용할 것인데 위치 체크 필요하다.
- 스프링 안에 있는 것이 아닌 – 바깥쪽인 서버의 필터 자리에 만들어 주자.
- proxy라는 기능 필요하다.
1-1 : proxy란?
- 감싸주는 것
- 어떤 객체를 만들면 – 이거를 사용할 때 실제로 이 객체를 바로 사용하는 것이 아닌 – 이 객체를 감싸고 있는 어떤 객체를 만들고 – 감싸고 있는 객체를 통해서 안쪽 객체가 작동하게 만드는 것 – 이것이 proxy
- 즉, 어떤 객체를 감싸주는 객체
- 우리가 사용한 것 중에는 sqlSEssion
- sst 프록시를 호출해서 ss를 사용하는 방식.
1-2 : DelegatingFilterproxy 사용 법
- spring이 제공하는 class를 이용해서 객체를 만들어서 서버의 filter자리에 등록해주면
- 그 객체가 작동하는것이아니라 – 요청을 떠넘기는 역할만 한다. 누구에게?
- spring이 관리하는 filter객체에게
- 실제 작동하는 객체는 스프링이 관리하는 filter가 된다.
- 즉, 바지사장으로 spring에서 관리하는 클래스로 - filter 등록해놓고 – 실제 작동하는 애한테 위임하게 해 주는 것
1-3 : DelegatingFilterproxy 사용하는 이유?
- 왜 스프링 바깥쪽에 있는 필터까지 먹으려고 하나? - 필터한테도 @Autowired해주고 싶어서
- 필터는 스프링 밖에 있어서 스프링이 영향을 못 준다.
- --- 필터에 내가 빈으로 등록해놓은 SST적용 못한다. --- 그래서 바지 사장 세워놓고 내가 등록한 필터로 가져오도록해주고 – 그 안에서 내가 코드 추가해서 SST 불러오고 사용할 수 있다.
- 즉, 스프링에서 관리하고 있는 다른 객체들을 필터에서도 사용하기 위해서 사용
- 요청은 필터에게 왔지만 결국 DB까지 다녀오는 작업 할 수 있다.
DelegatingFilterproxy ( 바지사장 / 대역 )
- -- 위임 전용 객체로 필터 객체 만들기 – 델리게이팅프록시필터
- -- 위임할 때는 bean name을 이용해서 위임
@Component - 빈 등록해놓은 필터 ( 실제 일하는 애 )
- 필터는 세워놓고 필터의 권한을 위임받아서 실제로 작동하는 것은 내가 만든 객체
2. 실습 - DelegatingFilterproxy
2-1 : 기존 방식으로 필터 등록해보기
- @WebFilter() 와 implement Filter로 만들었다.

2-2 : 스프링 방식에 맞게 등록해주기
- @Component 와 implement Filter로 만들기

# bean으로 등록해주어야 한다.
- @Component 등록해주어야 하는데 – 무엇으로 해줄까? - 그냥 @Componenet
- 이렇게 해주면 – 스프링 컨테이너 – 스프링 바구니 안에 등록이 된 상태이다
- 확인방법은? - spring Explorer에서 확인
- 이름은 카멜케이스 적용해서 자동으로 등록되었네
- 내가 원하는 이름은 @Component(value=“abc”) 이런 식으로 등록 가능
- 필터 등록할 때는 이름을 가지고 연결해줄 것이라서 이름이 중요하다!

servlet-context.xml바구니에 담겨있다.
스프링에 필터 등록은 완료
이제 나한테 위임해줄 바지사장 필터 만들어 주어야 한다..
바지사장의 위치는 스프링 밖 서버 쪽
2-3 : 바지사장 필터 만들기
- web.xml 에다가 바지 사장 필터 생성 - 등록
- 소문자 khFilter 로!
이때 등록한 filter-name을 가지고 실제 작동할 filter를 찾아가서 작동한다!
타입은 DelegatingFilterproxy 이고 이름은 실제 작동할 filter이름과 동일하게 !

2-4 : root-context 바구니에 담아주기
- 그래도 오류 난다. 왜 그럴까?
- 우리가 등록해놓은 KhFilter가 servlet-context 바구니에 담겨있어서 그렇다.
- root-context 바구니에 담겨있어야 한다.
spring이 root-context에 있는 것만 연결해준다 filter자리에는
web.xml에서 실행하려고 루트컨텍스트 찾아가 봤더니 없다고 에러 나는 것이다.
실행 시점에 차이가 있어서 못 찾는다. 에러난다.
# 프록시는 루트나 서블릿 컨텍스트 자리 상관없다 #
# 필터를 등록하는 경우에만 루트컨텍스트에 담아두어야한다 #
루트 컨텍스트에 담는 방법은?
- xml방식 또는 어노테이션 방식
- xml로 등록하는 것이 번거로우니 @ 어노테이션으로 해주자
- @Component 어노테이션이 동작하는 이유 - web.xml 참조 – component-scan이 작동해서 @Component 달려있으면 bean으로 만들어주는 것이다.
- root-context에 담는 이런 거는 없다. 그래서 빈 등록해놔도 루트컨텍스트에 담기지않는다.
- 없으니 추가해주자 - root-context에 담기도록 태그를 추가해보자.
# 네임스페이스 이용해서 root-context.xml 에 context 추가하기

# 해당 패키지 스캔해서 root-context에 담도록 추가
필터 등록 완료!
필터 관련 질문 타임
1. 바지사장 필터 등록과 @Qualifier
스프링에서는 이름 똑같은 거 찾아오는 어노테이션 명령이 있다.
@Qualifier

2. 필터의 관계와 위치
1번 - ok
2번
– 필터 자체가 일하는 게 아니라 필터는 바지로 세워놓고 내가 관리하는 객체가 이 필터 역할을 대신하게 해주는 것이다.
– 필터는 세워놓고 필터의 권한을 위임받아서 실제로 작동하는 것은 내가 만든 객체
– 무조건 root컨텍스트여야하는지 root컨텍스트랑 같은 레벨에 있으면 되는지 확실하지 않다
– 일단 서블릿 컨텍스트에 있으면 안 된다. - 전역인 애한테 있어야 한다로 정리
3. proxy
- 라이브러리 객체를 내가 마음대로 다루기 힘드니까 ( 수정하기 어려우니까 )
- 내가 만든 객체로 감싸서 이것저것 추가하거나 다루면서 사용하는 것
- DelegatingFilterproxy도 - 프록시 패턴의 한 가지이다.
3-1 : DelegatingFilterproxy
1단계 – 요청을 받으면 내가 지정해놓은 객체한테 요청 넘기는 역할만 하는 애를 세워놓기
( 내가 직접 만든 애 말고 그 작업을 하게 스프링에서 만들어놓은 애를 사용 )
( 지정방법은 name이 같은 애한테 넘기도록 지정 )
2단계 – 실제 일하는 것은 안쪽 객체
3-2 : proxy 작동원리
#예시 : s1객체의 start() 메서드를 호출하는 상황에서 메서드 실행시간 체크해라
- c1객체가 s1객체의 start() 메서드를 호출한다는 걸 아는데
- 바로 호출하게 해 주면 시간 체크하는 코드 넣기가 힘들다.
- 그래서 s1객체(=클래스) 쫙 읽어 드려서 가짜 클래스(=프록시)로 똑같이 만든 다음
- 내가 만든 프록시니까 앞뒤로 시간 체크하는 코드 추가할 수 있다.
- 이렇게 추가해 놓은 다음
- c1객체가 s1객체를 호출하는 것이 아닌 내가 만든 프록시를 호출하도록 해준다.
이런 동작하는 프록시 하나만 만들어놓으면
1000개의 서비스에 각각 추가할 필요 없이 모든 서비스에 대해서 작동 가능
지금 레벨에서 작동원리는 이해하기 어렵다
사용법 위주로 잘 익혀놓아 보자
reflection 공부하면 프레임워크 만들 수 있다......
4. Interceptor
- 가로채는 애 – 요청을 가로챔 -
- 언제 가로챔? -
- 1. DS-> Controller 갈 때 이때 가로챌 수 있다.
- 2. Controller -> DS 갈 때도 가로챌 수 있다.
- 3. 화면 보여주기 전에도 가로챌 수 있다.

4-1 : 인터셉터가 가로채는 3가지 시점
1번 시점 - 서블릿이 클라이언트의 요청을 받아서 컨트롤러에게 보내는 시점
- 스프링 프레임워크를 사용한다면
- 필터를 거치지 않았더라도 / 처음 요청을 처리하는 시점(=1번 시점)
- 이 시점에서 가로채서 어떤 작업을 한다면 필터를 사용하는 것과 같은 효과
2번 시점 - 컨트롤러에서 처리 후 서블릿으로 가는 시점
- . 컨트롤러가 디스패쳐한테 값을 제대로 넘길 때 가로채서 잘 넘겨주고 있나 확인도 가능
3번 시점 - 서블릿이 클라이언트에게 화면 응답하는 시점
- 디스패쳐가 화면을 선택해서 클라이언트에게 보여줄 때 예외를 발생할지 체크할 수 있다.
4-2 : 필터와 비슷하지만 차이점 존재
# 관리하는 영역과 시점의 차이
- 다만 필터는 스프링 밖에서 관리되는 애고 / 인터셉터는 스프링 안에서 관리되는 애
- 그리고 필터랑 비슷하지만 , 시점이 3개인 애
# 받아주는 요청의 종류 차이
- 필터는 파일리퀘스트 , 무슨 리퀘스트 등 모든 리퀘스트를 받아주지만
- 인터셉터는 보다 구체적인 우리가 원하는 http관련 리퀘스트만 받아준다.
5. 실습 - 인터셉터 만들기
5-1 : 클래스 만들기
5-2 : 인터셉터로 만들기 ( 클래스상속, 인터페이스 상속 )
- extends
HandlerInterceptorAdapter - implements HandlerInterceptor
# 클래스 상속은 더 이상 지원하지 않는다고 하니까인터페이스 상속으로 진행
- 인터페이스 상속 받았지만 default 메서드로 만들어져있어서 당장 메서드 구현하라는 에러 안나온다.
- ( 디폴트메서드 궁금하면 검색해서 알아보기 – 디폴트메서드는 메서드body부분도 작성되어있다.)
5-3 : 사용할 메서드 @Override 해주기
- preHandle ::: DS->Controller 이 시점에 간섭하는애

5-4 : servlet-context 에 객체 담아주고 테스트 ( DS에서 나가고 들어오고 할 때 알아야 하므로 )

지금 상황은 클라이언트에 들어온 요청을 처리하는 애가 누구인가 확인해본 상태이다.
요청이 들어와서 DS는 핸들러 매핑에 다녀와서
어떤 컨트롤러한테 가라고 받은 상태에서
가고 있는데 그 중간에 가로채서 누구한테 가는지 확인해본 상태

이런 상태에서 - 확인해보는 것뿐만 아니라
여러 가지 검사(파라미터검사나 누구한테 가고있는지나)해보고
마음에 안 든다 하면 이 요청이 안 가게 할 수 있다.
방법은?
preHandel - return false; 해주면된다.
6. 인터셉터 메서드
- preHandle()
- postHandle()
- afterCompletion()


#1 - preHandle 호출되고 – 핸들러실행되고 – postHandle 작동
#2 - 모델앤뷰는 – model에 담겨있는 데이터를 확인할 수 있고– view에 다음으로 이동하는 곳을 알 수 있다!!
이미 갔다 왔으므로return 값으로 막아줄 수 없다.
#3 - afterCompletion ㅡ viewPage ( home.jsp) 까지 출력된 다음에 ㅡ afterCompltion 실행된다.
#4 - 화면페이지에있는 글 출력
#5 -화면쪽에서 예외가 발생했다면 여기에 null이 아니라 예외상황이 들어있을 것이다.
7. 인터셉터를 사용하는 이유
# 장점
- 3가지 시점에 필터처럼 사용가능
- DS를 거쳐 컨트롤러로 가는 지점에서 처리하기 떄문에 우리가 원하는 요청에 대해서만 작업 가능
- 특정 경로는 제외하는 기능도 가능 <exclude-mapping>
- 모니터링이나 특정url관리나 문자열많이오면 압축처리하는 작업, 권한 처리 등 필터 가능
#단점
- 404에러처리는 안돼요- 왜?
- 인터셉터는 언제 동작하냐면 서블릿 다음에 or 다녀와서
- 근데 404 에러는 연결된 게 없을 때 나오는 에러다. 일단 오기라도 해야지 처리할 텐데 안된다.
- 예외처리는 필터나 인터셉터 말고 다른 걸로 한다. - 컨트롤러 어드바이스
# exclude-mapping
- 필터에 ㅡ 로그인 안 한 경우 /member/** 경로로 오는 모든 요청 막아놓았다.
- 근데 /member/login 은 어떻게 할 것인가?
- login 빼고 나머지 다 통과시켜주려고 나머지를 다 필터 url에 등록해야 한다? 노노
- 인터셉터는 특정 url 제외하는 게 된다.
- exclude-mapping을 이용

8. 인터셉터 정리
인터셉터를 만들고 ( implements HandleInterceptor)
실제 대상의 작업이 이루어지기 전에
앞쪽에 이런 작업이 이루어지도록 해주겠다 – preHandle 메서드에
작업이 끝난 후에 이루어지는 작업은 postHandle 메서드에 작성
어느 요청에 대해서 작업할 것인지 지정해주면 된다.
예외를 처리하는 목적보다는 – 예외를 감시하고 – 예외를 기록하는 목적으로 많이 사용한다.
인터셉터는 – 감시하는 역할이 더 어울린다고 생각한다.
지금 상황이 어떤지 로그 같은 거 남길 때 사용하면 좋다.
AOP:관점지향프로그래밍
인터셉터가 AOP를 적용한 대표적인 애중에 하나이다.
'Java 기반 클라우드 융합 개발자 과정 - KH 정보교육원 > 9월' 카테고리의 다른 글
22.09.20 - [ Spring ] tx(트랜잭션), AOP(관점지향프로그래밍) (1) | 2022.09.29 |
---|---|
22.09.19 - [ Spring ] lombok, controlllerAdvice, logger (0) | 2022.09.28 |
22.09.15 - [ Spring ] 암호화 처리, 리다이렉트 방법 (0) | 2022.09.21 |
22.09.14 - [ Spring ] Spring 작동 원리 , mapper.xml 파일 연결하기 (0) | 2022.09.20 |
22.09.13 - [ Spring ] pom.xml / web.xml / context.xml 설정 파일 및 DB 설정 파일 (0) | 2022.09.19 |