3

私はjavaSEでweldの非常に単純な実装をセットアップしようとしています。

私は拡張クラスを持っています:

public class MyExtension implements Extension {

    void beforeBeanDiscovery(@Observes BeforeBeanDiscovery bbd) {
        System.out.println("Starting scan...");
    }      
    <T> void processAnnotatedType(@Observes ProcessAnnotatedType<T> annotatedType, BeanManager beanManager) {
        System.out.println("Scanning type: " + annotatedType.getAnnotatedType().getJavaClass().getName());
    } 
    void afterBeanDiscovery(@Observes AfterBeanDiscovery abd) {
        System.out.println("Finished the scanning process");
    }

    public void main(@Observes ContainerInitialized event) {
        System.out.println("Starting application");
        new Test();
    }
}

次に、注入したい単純なクラスがあります。

public class SimpleClass {
    public void doSomething() {
        System.out.println("Consider it done");
    }
}

そして最後に、私がそれを注入したいクラス:

public class Test {

    @Inject
    private SimpleClass simple;

    @PostConstruct
    public void initialize() {
        simple.doSomething();
    }

    @PreDestroy
    public void stop() {
        System.out.println("Stopping");
    }
}

結果の出力は次のとおりです。

80 [main] INFO org.jboss.weld.Version - WELD-000900 1.1.10 (Final)
272 [main] INFO org.jboss.weld.Bootstrap - WELD-000101 Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
Starting scan...
Scanning type: test.Test
Scanning type: test.SimpleClass
Scanning type: test.MyExtension
640 [main] WARN org.jboss.weld.interceptor.util.InterceptionTypeRegistry - Class 'javax.ejb.PostActivate' not found, interception based on it is not enabled
640 [main] WARN org.jboss.weld.interceptor.util.InterceptionTypeRegistry - Class 'javax.ejb.PrePassivate' not found, interception based on it is not enabled
Finished the scanning process
Starting application

Test()が構築され、期待されるテキストを出力するpostconstructメソッドが呼び出されるときに、単純なクラスが注入されることを期待します。

私は正確に何を間違っているのですか?

4

3 に答える 3

5

コードには2つの問題があります。

問題1

CDIは、で作成されたBeanを管理しませんnew。ほとんどの場合、Beanのライフサイクルをコンテナで管理するには、Beanを@Injectする必要があります。

問題2:

ほとんどの場合、Beanインスタンスをコンテナイベントのオブザーバーに挿入することはできません。これは、コンテナが初期化されているときにイベントが発生しているためです。つまり、オブジェクトのライフサイクルの管理を実際に開始する前です。

コンテナ初期化オブザーバーをTestクラスに直接フックすることができます。このようなもの:

public class SimpleClass {
    public void doSomething() {
        System.out.println("Consider it done");
    }

   @PostConstruct
    public void initialize() {
        System.out.println("Starting");
    }

    @PreDestroy
    public void stop() {
        System.out.println("Stopping");
    }
}

public class Test {

    @Inject
    private SimpleClass simple;

    public void main(@Observes ContainerInitialized event) {
        System.out.println("Starting application");
        simple.doSomething();
    }       
}
于 2013-01-25T11:58:17.157 に答える
0

あなたが間違っているのは、を呼び出すことですnew Test()。これにより、Testの新しいインスタンスが作成されますが、CDIの背後にあります。CDIがテストインスタンスを注入するには、CDIがそれ自体を作成する必要があります。

Java SE環境でWeldをブーストラップする方法については、ドキュメントを参照してください。

于 2013-01-25T12:03:59.963 に答える
0

@ApplicationScopedを使用してutilsクラスを作成します。このクラスは、あらゆるタイプのオブジェクトを生成できます。あなたの場合、これは次のようになります。

@Produces
static SimpleClass generateSimpleClass(){
return new SimpleClass();
}

それ以外の場合、simpleclassがアプリケーション内で一意のクラスになる場合は、そのクラスを@ApplicationScopedとして設定します。問題は、アノテーションもプロデューサーもない場合、weldはクラスがコンテナーに属していることを認識しないことです。

于 2013-02-15T13:45:15.600 に答える