Backend/Spring+Boot

DelegatingFilterProxy

findmypiece 2021. 3. 17. 11:57
728x90

Servlet은 ServletContext를 사용하고 Spring은 ApplicationContext를 사용한다.

또한 ServletFilter는 ServletContext에서 동작하기 때문에

기본적으로 ApplicationContext 에 있는 Spring Bean을 참조하지 못한다.

하지만 ServletFilter에서 Spring Bean을 사용하고 싶은 경우가 있다.

그 때 DelegatingFilterProxy 를 활용하면 된다.

 

DelegatingFilterProxy는 Spring에서 제공하는 ServletFilter 이기 때문에

ServletContext 에서 ServletFilter 지정시 DelegatingFilterProxy 객체를 지정하면 되고

생성자 인자로 Spring Bean 이름을 명시하면 Filter 처리를 해당 Bean 에 위임한다.

 

이 때 지정하는 Spring Bean은 GenericFilterBean 을 상속한 클래스여야 한다.

참고로 OncePerRequestFilter 이 결국 GenericFilterBean를 상속한 것이니

OncePerRequestFilter를 상속한 Bean도 상관없다.

 

GenericFilterBean 를 상속한 Bean은 ApplicationContext 에서 관리되기 때문에

Spring의 DI 기능을 마음 껏 활용할 수 있게 된다. (@Autowired 같은..)

결국 ServletFilter 에서 Spring Bean을 사용할 수 있게 된다는 말이다.

 

하지만 SpringBoot의 등장으로 이 기술을 코드상에서 직접 사용하는 경우는 많지 않다.

내장 Tomcat을 사용하게 되면서 ServletFilter 와 Spring Bean 연결을 자동으로 해주기 때문이다.

 

Spring의 역사를 대략 살펴보면

3.1 버전 부터 서블릿3.0이 도입되어 web.xml 없이 WebApplicationInitializer 인터페이스 구현을 통해

ServletContext 설정이 가능해졌다.

3.2 버전 부터는 WebApplicationInitializer 구현한 AbstractAnnotationConfigDispatcherServletInitializer가

기본으로 제공되어 좀 더 편하게 ServletContext를 설정할 수 있게 됐다.

이때까지만해도 ServletFilter에서 Spring Bean 을 사용하려면 DelegatingFilterProxy를 직접 사용해야 했다.

하지만 SpringBoot에서는 기본적으로 GenericFilterBean 을 상속한 클래스를 생성해서

Spring Bean으로 포함시키기만 하면 ServletFilter 로 동작한다.

 

물론 SpringBoot 인데도 외부 톰캣을 사용할 경우 ServletContext 를 직접 설정해야 하고

그때는 DelegatingFilterProxy 을 활용해야 할 수도 있다.

728x90