7.11. 인터셉터

인터셉터를 사용하면 빈의 방법을 직접 수정하지 않고도 빈의 비즈니스 메서드에 기능을 추가할 수 있습니다. 인터셉터는 빈의 비즈니스 방법보다 먼저 실행됩니다. 인터셉터는 Jakarta Enterprise Beans 사양의 일부로 정의됩니다.

Jakarta Contexts and Dependency Injection은 주석을 사용하여 인터셉터를 bean에 바인딩할 수 있어 이 기능을 향상시킵니다.

인터셉션 포인트

  • 비즈니스 방법 가로채기: 비즈니스 메서드 인터셉터는 빈의 클라이언트가 빈 메서드 호출에 적용됩니다.
  • 라이프 사이클 콜백 인터셉션: 라이프사이클 콜백 인터셉터는 컨테이너에서 라이프사이클 콜백 호출에 적용됩니다.
  • timeout 메서드 인터셉션: timeout 메서드 인터셉터는 컨테이너에서 Jakarta Enterprise Beans 시간 제한 메서드를 호출하는 데 적용됩니다.

인터셉터 활성화

기본적으로 모든 인터셉터는 비활성화됩니다. 빈 아카이브의 bean.xml 설명자를 사용하여 인터셉터를 활성화할 수 있습니다. 그러나 이 활성화는 해당 아카이브의 빈에만 적용됩니다.

@Priority 주석을 사용하여 전체 애플리케이션에 대한 인터셉터를 활성화할 수 있습니다.

예제: bean.xml에서 인터셉터 활성화

<beans
   xmlns="http://xmlns.jcp.org/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
      http://xmlns.jcp.org/xml/ns/javaee
      http://xmlns.jcp.org/xml/ns/javaee/beans_2.0.xsd">
   <interceptors>
      <class>org.mycompany.myapp.TransactionInterceptor</class>
   </interceptors>
</beans>

XML 선언을 사용하면 두 가지 문제가 해결됩니다.

  • 이를 통해 시스템의 인터셉터 순서를 지정하여 결정적인 동작을 보장할 수 있습니다.
  • 배포 시 인터셉터 클래스를 활성화하거나 비활성화할 수 있습니다.

@Priority 를 사용하여 활성화된 인터셉터는 beans.xml 파일을 사용하여 인터셉터를 활성화하기 전에 호출됩니다.

참고

인터셉터를 @Priority 에서 활성화하고 동시에 beans.xml 파일에서 호출하면 포팅할 수 없는 동작이 발생합니다. 따라서 다양한 Jakarta Contexts 및 Dependency Injection 구현에서 일관된 동작을 유지하려면 활성화의 조합을 피해야 합니다.

7.11.1. 자카르타 컨텍스트 및 종속성 주입과 인터셉터 사용

Jakarta Contexts and Dependency Injection을 사용하면 인터셉터 코드를 단순화하고 비즈니스 코드에 더 쉽게 적용할 수 있습니다.

자카르타 컨텍스트 및 종속성 주입이 없으면 인터셉터에는 두 가지 문제가 있습니다.

  • 빈은 인터셉터 구현을 직접 지정해야 합니다.
  • 애플리케이션의 모든 빈은 올바른 순서로 전체 인터셉터 세트를 지정해야 합니다. 이로 인해 애플리케이션 전체에서 인터셉터를 추가하거나 제거할 수 있으며 오류가 발생하기 쉽습니다.
자카르타 컨텍스트 및 종속성 주입과 인터셉터 사용
  1. 인터셉터 바인딩 유형을 정의합니다.

    @InterceptorBinding
    @Retention(RUNTIME)
    @Target({TYPE, METHOD})
    public @interface Secure {}
  2. 인터셉터 구현을 표시합니다.

    @Secure
    @Interceptor
    public class SecurityInterceptor {
      @AroundInvoke
      public Object aroundInvoke(InvocationContext ctx) throws Exception {
        // enforce security ...
        return ctx.proceed();
        }
    }
  3. 사용자의 개발 환경에서 인터셉터를 사용합니다.

    @Secure
    public class AccountManager {
      public boolean transfer(Account a, Account b) {
        ...
      }
    }
  4. META-INF/beans.xml 또는 WEB-INF/beans.xml 파일에 추가하여 배포에서 인터셉터를 활성화합니다.

    <beans>
      <interceptors>
        <class>com.acme.SecurityInterceptor</class>
        <class>com.acme.TransactionInterceptor</class>
      </interceptors>
    </beans>

인터셉터는 나열된 순서대로 적용됩니다.