Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

InterceptorBinding is not working

I created a custom annotation like below

@InterceptorBinding
@Retention(RUNTIME)
@Target(TYPE, METHOD)
public @interface Traceable {}

I wrote an interceptor like below

@Traceable
@Interceptor
public class EnterExitLogger {
    @AroundInvoke
    public Object aroundInvoke(InvocatiobContext c) {}
}

The interceptor and the annotation are in a module called common-utils.

I annotated a my target class with @Traceable at class level like below

@Traceable
public class CDIManagedBean {
}

I declared the interceptor entry in my beans.xml file like below

<interceptors>
    <class>my.package.EnterExitLogger</class>
</interceptors>

The target class is in a separate module. beans.xml is in META-INF directory of the target class's module.

The target class's methods are called from a rest class. When I invoke the methods the interceptor's AroundInvoke method is not called.

I read the docs and understood that the interceptor should contain a public no argument constructor. I added it. But still the interceptor was not called.

I added @Inherited on the custom annotation after reading the docs. But still the interceptor was not called.

From the docs I noticed the interceptor implementing Serializable interface. Although not mentioned I implemented Serializable also. Still did not work.

Then I removed the custom annotation from the interceptor, beans.xml file and the target class. I also removed the public no argument constructor from the interceptor and removed Serializable.

Then I annotated the target class with @Interceptors(EnterExitLogger.class) and invoked the flow. My interceptor was called.

Can anyone tell me how do I do with an InterceptorBinding?

P.S.

I am deploying my ear in WAS 8.5 server.

like image 384
Krishna Chaitanya Avatar asked Oct 22 '15 12:10

Krishna Chaitanya


1 Answers

The Java EE Tutorial provides a nice explanation and a few examples about interceptors:

Create an interceptor binding annotation, which must be annotated with @Inherited and @InterceptorBinding:

@Inherited
@InterceptorBinding
@Retention(RUNTIME)
@Target({METHOD, TYPE})
public @interface Logged { }

Create the incerceptor class which is annotated with the interceptor binding annotation created above as well as with the @Interceptor annotation.

Every @AroundInvoke method takes an InvocationContext argument, returns an Object, and throws an Exception. The @AroundInvoke method must call the InvocationContext#proceed() method, which causes the target class method to be invoked:

@Logged
@Interceptor
public class LoggedInterceptor implements Serializable {

    public LoggedInterceptor() {

    }

    @AroundInvoke
    public Object logMethodEntry(InvocationContext invocationContext) throws Exception {

        System.out.println("Entering method: "
                + invocationContext.getMethod().getName() + " in class "
                + invocationContext.getMethod().getDeclaringClass().getName());

        return invocationContext.proceed();
    }
}

Once an interceptor and binding type are defined, you can annotate beans and individual methods with the binding type to specify that the interceptor is to be invoked either on all methods of the bean or on specific methods.

For example, the PaymentHandler bean is annotated @Logged, which means that any invocation of its business methods will cause the interceptor's @AroundInvoke method to be invoked:

@Logged
@SessionScoped
public class PaymentHandler implements Serializable {...}

However you can intercept only a set of methods of a bean by annotating only the desired methods:

@Logged
public String pay() {...}

@Logged
public void reset() {...}

In order for an interceptor to be invoked in a CDI application, it must be specified in the beans.xml file:

<interceptors>
    <class>your.package.LoggedInterceptor</class>
</interceptors>

If an application uses more than one interceptor, the interceptors are invoked in the order specified in the beans.xml file.

like image 86
cassiomolin Avatar answered Nov 07 '22 13:11

cassiomolin