Search

7.11. Seam interceptors

download PDF
EJB3 introduced a standard interceptor model for session bean components. To add an interceptor to a bean, you need to write a class with a method annotated @AroundInvoke and annotate the bean with an @Interceptors annotation that specifies the name of the interceptor class. For example, the following interceptor checks that the user is logged in before allowing invoking an action listener method:
public class LoggedInInterceptor { 
    @AroundInvoke 
    public Object checkLoggedIn(InvocationContext invocation) 
        throws Exception { 
        boolean isLoggedIn = Contexts.getSessionContext()
            .get("loggedIn")!=null; 
        if (isLoggedIn) { 
            //the user is already logged in return invocation.proceed(); 
        } else { 
            //the user is not logged in, fwd to login page return "login"; 
        } 
    } 
}
To apply this interceptor to a session bean acting as an action listener, we must annotate the session bean @Interceptors(LoggedInInterceptor.class). However, Seam builds upon the interceptor framework in EJB3 by allowing you to use @Interceptors as a meta-annotation for class level interceptors (those annotated @Target(TYPE)). In this example, we would create an @LoggedIn annotation, as follows:
@Target(TYPE) 
@Retention(RUNTIME) 
@Interceptors(LoggedInInterceptor.class) 
    public @interface LoggedIn {}
We can now annotate our action listener bean with @LoggedIn to apply the interceptor.
@Stateless 
@Name("changePasswordAction") 
@LoggedIn 
@Interceptors(SeamInterceptor.class) 
public class ChangePasswordAction implements ChangePassword { 
    ... 
        public String changePassword() { 
            ... 
        } 
}
Where interceptor order is important, add @Interceptor annotations to your interceptor classes to specify a particular order of interceptors.
@Interceptor(around={BijectionInterceptor.class, 
                     ValidationInterceptor.class, 
                     ConversationInterceptor.class}, 
    within=RemoveInterceptor.class) 
public class LoggedInInterceptor { 
    ... 
}
You can even have a client-side interceptor, for built-in EJB3 functions:
@Interceptor(type=CLIENT) 
public class LoggedInInterceptor { 
    ... 
}
EJB interceptors are stateful, and their lifecycles match that of the component they intercept. For interceptors that do not need to maintain state, Seam allows performance optimization where @Interceptor(stateless=true) is specified.
Much of Seam's functionality is implemented as a set of built-in Seam interceptors, including the interceptors named in the previous example. These interceptors exist for all interceptable Seam components; you need not specify them explicitly through annotation.
Seam interceptors can also be used with JavaBean components.
EJB defines interception not only for business methods (using @AroundInvoke), but also for the lifecycle methods @PostConstruct, @PreDestroy, @PrePassivate and @PostActive. Seam supports these lifecycle methods on both component and interceptor, not only for EJB3 beans, but also for JavaBean components (except @PreDestroy, which is not meaningful for JavaBean components).
Red Hat logoGithubRedditYoutubeTwitter

Learn

Try, buy, & sell

Communities

About Red Hat Documentation

We help Red Hat users innovate and achieve their goals with our products and services with content they can trust.

Making open source more inclusive

Red Hat is committed to replacing problematic language in our code, documentation, and web properties. For more details, see the Red Hat Blog.

About Red Hat

We deliver hardened solutions that make it easier for enterprises to work across platforms and environments, from the core datacenter to the network edge.

© 2024 Red Hat, Inc.