我有CDI拦截器的问题。在我的EJB模块中,我创建了拦截器注释及其实现,我还在beans.xml中添加了实现类。我有一个名为AbstractFacade的抽象类,并且从它派生了一些类。在一个类中,我重写create方法并向其添加拦截器注释。现在在web模块中我有ejb bean的实例和拦截器注释,但是引用它有AbstractFacade类型。当我在这个引用上调用create方法时,在ejb模块中调用了适当的metod(这个带有注释),但是我的拦截器没有被调用,但是如果我将这个引用转换为它的真实类型并且调用create interceptor将正常工作。我不确定我是否能够很好地描述它,所以这里是代码:
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);
}
}
好的,这是在战争中:
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
}
}
我不知道为什么getFacade()。create(entity);不会发射拦截器。我会很高兴得到任何帮助。
答案 0 :(得分:0)
我的回答可能有点偏离主题,但我正在从JSF托管bean迁移到CDI托管bean,我刚刚确认我能够在后代CDI中成功使用super bean(带有'自定义'@Descendant限定符),'扩展'祖先CDI bean(使用@Default限定符)。
使用@Default限定符的CDI bean祖先:
@Default
@Named("pf_pointOfContactController")
@SessionScoped
public class pf_PointOfContactController implements Serializable {
Ancestor bean有以下内容:
@PostConstruct
protected void init() {
带有@Descendant限定符的CDI bean后代:
@Descendant
@Named("pf_orderCustomerPointOfContactController")
@SessionScoped
public class pf_OrderCustomerPointOfContactController extends pf_PointOfContactController {
后代bean有以下内容:
@PostConstruct
public void init(){
super.init();
我必须添加/使用super.init(),因为祖先CDI bean中的方法引发了NullPointerException,因为祖先bean的@PostConstruct没有在CDI @Descendant bean中执行。
我已经看到/听到/读过在使用CDI时建议使用@PostConstruct而不是Constructor方法,因此祖先bean的构造函数具有'初始化'逻辑,并且在使用JSF时自动调用/执行祖先bean的构造函数托管豆。