4

CDIインターセプターに問題があります。私の EJB モジュールでは、インターセプター アノテーションとその実装を作成し、beans.xml に実装クラスも追加しました。AbstractFacade という名前の抽象クラスと、そこから派生したいくつかのクラスがあります。あるクラスでは、create メソッドをオーバーライドし、インターセプター アノテーションをそれに追加します。Web モジュールには、インターセプター アノテーションを持つ ejb Bean のインスタンスがありますが、それへの参照には AbstractFacade タイプがあります。この参照で create メソッドを呼び出すと、ejb モジュールの適切なメソッドが呼び出されますが (これは注釈付き)、インターセプターは呼び出されませんが、この参照を実際の型にキャストして create インターセプターを呼び出すと、適切に動作します。うまく説明できたかどうかわからないので、コードを次に示します。

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();
    }
}

ビーンズ.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); の理由がわかりません。インターセプターを発射しません。どんな助けでも大歓迎です。

4

1 に答える 1

0

私の答えは少しトピックから外れているかもしれませんが、私は JSF Managed Bean から CDI Managed Bean に移行する過程にあり、子孫 CDI Bean でsuperを正常に使用できることを確認しました (「カスタム」@祖先 CDI Bean を「拡張」する子孫修飾子 (@Default 修飾子を使用)。

@Default 修飾子を持つ CDI Bean 祖先:

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

祖先 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();

祖先 Bean の @PostConstruct が CDI @Descendant Bean で実行されないため、祖先 CDI Bean のメソッドが NullPointerException を発生させていたため、super.init() を追加/使用する必要がありました。

CDI を使用する場合は、Constructor メソッドの代わりに @PostConstruct を使用することをお勧めします。そのため、先祖 Bean のコンストラクターには「初期化」ロジックがあり、先祖 Bean のコンストラクターは、JSF マネージド Bean を使用するときに自動的に呼び出されて実行されました。

于 2012-11-21T07:53:10.223 に答える