【问题标题】:@Inject delivers null in Weld 3 using Java SE@Inject 使用 Java SE 在 Weld 3 中提供 null
【发布时间】:2018-01-09 10:33:16
【问题描述】:

我在一个普通的 Java SE 8 程序中使用 CDI 2.0 和 Weld 3.0.0 final(类路径中的完整weld-se-shaded.jar),如下所示。它有什么问题或者我错过了什么,因为@Inject 什么都不做,即引用保持为空?如图所示的程序化访问。

我想将此发布到 JBoss/Weld Jira 错误跟踪系统中。但是,注册登录后,我找不到创建新条目的按钮。

感谢您的帮助,

StartUp.java

import javax.enterprise.inject.se.SeContainer;
import javax.enterprise.inject.se.SeContainerInitializer;

public class StartUp {

    public static void main(String[] args) {
        // start CDI Container
        SeContainerInitializer initializer = SeContainerInitializer.newInstance();        
        try (SeContainer container = initializer.initialize()) {
            Test t = new Test();

            // start tests
            t.test(container);
        }
    }

}

Test.java

import javax.enterprise.event.Event;
import javax.enterprise.inject.se.SeContainer;
import javax.enterprise.inject.spi.CDI;
import javax.inject.Inject;

public class Test {

    @Inject
    // IMyBean myBean;    // does not work
    MyBean myBean;    // does not work

    @Inject
    Event<UserEvent> event;     // does not work

    public void test(SeContainer container) {
        myBean.greete("World");               // NullPointerException

        // manual lookup
        // MyBean myBean2 = container.select(MyBean.class).get();
        IMyBean myBean2 = CDI.current().select(IMyBean.class).get();
        myBean2.greete("World");

        event.fire(new UserEvent("info"));    // NullPointerException
    }

}

MyBean.java

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;

@Named
@ApplicationScoped
public class MyBean implements IMyBean {

    public void greete(String s) {
        System.out.println("Hello, " + s + "!");
    }

}

SyncEventObserver.java

import javax.enterprise.event.Observes;

public class SyncEventObserver {

    public void observeUserEvent(@Observes UserEvent userEvent) {
        System.out.println("Received event:" + userEvent.getMessage());
    }

}

UserEvent.java

public class UserEvent {
    private String message;

    public UserEvent() {
    }

    public UserEvent(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

}

META-INF/beans.xml

<beans version="2.0" bean-discovery-mode="all"
       xmlns="http://xmlns.jcp.org/xml/ns/javaee"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                           http://xmlns.jcp.org/xml/ns/javaee/beans_2_0.xsd">

</beans>

IMyBean.java

import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;

@Named
@ApplicationScoped
public interface IMyBean {

    void greete(String s);

}

【问题讨论】:

    标签: java dependency-injection cdi inject weld


    【解决方案1】:

    你的主要方法应该是这样的

    public static void main(String[] args) {
        // start CDI Container
        SeContainerInitializer initializer = SeContainerInitializer.newInstance();        
        try (SeContainer container = initializer.initialize()) {
            Test t = container.select(Test.class).get();
    
            // start tests
            t.test(container);
        }
    }
    

    原因是 - 您的测试类中有注入点,但您将其实例化。这使 CDI 不再管理您的 bean。

    【讨论】:

    • 哇,谢谢约翰。那成功了。然而,对我来说,一旦自我实例化,CDI 就会被切断,这似乎是一个相当强的限制。
    • 我不确定你的意思?这就是依赖注入的全部意义所在,您无需管理类的生命周期。
    猜你喜欢
    • 2014-11-06
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 2016-02-14
    相关资源
    最近更新 更多