[java] Guice를 이용한 서블릿 인터셉터(Interceptor) 구현

개요

서블릿 인터셉터는 서블릿 요청과 응답에 대해 사전 또는 사후 처리를 수행하는 기능을 가지고 있습니다. 이 기능은 Guice DI(Dependency Injection) 프레임워크를 사용하여 쉽게 구현할 수 있습니다. 이 블로그 포스트에서는 Guice를 이용하여 서블릿 인터셉터를 구현하는 방법에 대해 알아보겠습니다.

Guice 설정

먼저, Guice를 프로젝트에 설정해야 합니다. pom.xml 파일에 다음 의존성을 추가합니다:

<dependency>
    <groupId>com.google.inject</groupId>
    <artifactId>guice</artifactId>
    <version>5.0.1</version>
</dependency>

Guice 모듈을 정의하기 위해 클래스를 생성합니다. 이 클래스는 AbstractModule을 상속받아 구현합니다. configure() 메서드에서 서블릿 인터셉터를 바인딩합니다:

import com.google.inject.AbstractModule;

public class MyAppModule extends AbstractModule {
    @Override
    protected void configure() {
        bindInterceptor(Matchers.any(), Matchers.annotatedWith(MyInterceptor.class),
                new MyInterceptorHandler());
    }
}

위 코드에서 MyInterceptor 어노테이션이 적용된 클래스들에 대해 MyInterceptorHandler 클래스를 인터셉터로 사용하도록 설정하였습니다.

인터셉터 구현

MyInterceptorHandler 클래스를 구현하여 인터셉터의 동작을 정의합니다. 이 클래스는 MethodInterceptor 인터페이스를 구현해야 합니다. 다음은 간단한 예시 코드입니다:

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MyInterceptorHandler implements MethodInterceptor {
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        // 사전 처리 작업
        
        Object result = methodInvocation.proceed();
        
        // 사후 처리 작업
        
        return result;
    }
}

위 코드에서 invoke() 메서드는 사전 처리 작업 후, 실제 메서드를 호출하고 사후 처리 작업을 수행합니다.

어노테이션 정의

인터셉터를 적용할 클래스에 MyInterceptor 어노테이션을 정의합니다:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyInterceptor {
}

위 코드에서 MyInterceptor 어노테이션은 클래스에만 적용 가능하며, 런타임까지 유지됩니다.

서블릿 설정

서블릿을 Guice로 설정하여 인터셉터를 적용할 수 있습니다. 예를 들어, web.xml 파일에 다음과 같이 설정합니다:

<web-app>
    <listener>
        <listener-class>com.example.MyAppListener</listener-class>
    </listener>
    
    <filter>
        <filter-name>guiceFilter</filter-name>
        <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
</web-app>

위 설정은 MyAppListener 클래스를 Guice ServletContextListener로 등록하고, GuiceFilter를 모든 URL 패턴에 적용합니다.

마무리

이제 Guice를 이용하여 서블릿 인터셉터를 구현하는 방법에 대해 알아보았습니다. Guice의 강력한 DI 기능을 활용하면 코드 중복을 줄이고 유지보수성을 향상시킬 수 있습니다. Guice에 대해 더 알고 싶다면 공식 문서를 참조하세요.