CDI interceptor in extended class does not work if reference to base class is called form

I have a problem with CDI interceptors. In my EJB module, I am creating an interceptor annotation and my implementation, I also added an implementation class to beans.xml. I have an abstract class called AbstractFacade, and some classes are made from it. In one class, I override the create method and add my interceptor annotation to it. Now in the web module I have an ejb bean instance with an interceptor annotation, but the link to it is of type AbstractFacade. When I call the create method on this link, the corresponding method in the ejb module is called (this one with the annotation), but my interceptor is not called, but if I pass this link to its real type and the create interceptor call will work correctly. I'm not sure if I managed to describe it well, so here are the codes:

FooInter.java

package foo; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import javax.interceptor.InterceptorBinding; @InterceptorBinding @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface FooInter{} 

FooInterImpl.java

 package foo; import javax.interceptor.AroundInvoke; import javax.interceptor.Interceptor; import javax.interceptor.InvocationContext; @Interceptor @FooInter public class FooInterImpl { @AroundInvoke public Object fuckCall(InvocationContext context) throws Exception { System.out.println("Interceptor: it works"); return context.proceed(); } } 

beans.xml

 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd"> <interceptors> <class>foo.FooInterImpl</class> </interceptors> </beans> 

AbstractFacade.java

 public abstract class AbstractFacade<T> { //... public void create(T entity) { //... } } 

Foofacade.java

 @Stateless public class FooFacade extends AbstractFacade<Foo> { //... @Override @FooInter public void create(Foo entity) { super.create(entity); } } 

OK, and this is at war:

EditHelper.java

 public abstract class EditHelper<T> { protected T entity; //... protected abstract AbstractFacade<T> getFacade(); public void save() { //... //if T is foo and getFacade returns FooFacade, interceptor won't be called here! getFacade().create(entity); } } 

FooEditHelper.java

 public class FooEditHelper extends EditHelper<Foo> { @EJB private FooFacade fooFacade; //... protected AbstractFacade<T> getFacade() { return fooFacade; } @Override public void save() { getFacade().create(entity); //interceptor won't works !!!!!!!!!!! ((FooFacade)getFacade()).create(entity); //but here interceptor will work } } 

I do not know why getFacade (). create (entity); will not fire an interceptor. I will be very happy for any help.

+4
source share
1 answer

My answer may be a little off topic, but I'm in the process of migrating from JSF Managed beans to managed CDI beans, and I just confirmed that I can use super in a streaming CDI bean (with a "custom" @Descendant classifier) ​​that "extends" "The bean CDI predecessor (with the @Default classifier).

CDI bean ancestor with @Default classifier:

 @Default @Named("pf_pointOfContactController") @SessionScoped public class pf_PointOfContactController implements Serializable { 

The bean ancestors have the following:

 @PostConstruct protected void init() { 

CDI bean descendant with @Descendant classifier:

 @Descendant @Named("pf_orderCustomerPointOfContactController") @SessionScoped public class pf_OrderCustomerPointOfContactController extends pf_PointOfContactController { 

The bean descendant has the following:

 @PostConstruct public void init(){ super.init(); 

I had to add / use super.init () because the methods in the ancestor of the CDI bean raised a NullPointerException, since the ancestor of the bean @PostConstruct is not executed in the CDI @Descendant bean.

I saw / heard / read that when using CDI it is recommended to use the @PostConstruct method instead of the Constructor method, therefore the preform bean constructor had initialization logic, and the ancestor bean constructor was automatically called / executed when using JSF managed beans.

0
source

Source: https://habr.com/ru/post/1447373/


All Articles