java - 未注入(inject)内部依赖项(Weld + JavaSE)

标签 java cdi weld

我正在通过添加 CDI 重构旧模块。

我结束于

public interface ApiFactory {
  ...
}

public class ApiFactorySp
    implements ApiFactory {
  @Inject
  UrlProducer urlProducer;  // <-- Does not get injected
  ...
}

public interface UrlProducer {
    public String getUrl();
}

@Alternative
public class UrlProducerTest
    implements UrlProducer {

    @Override
    public String getUrl() {
        return "https://myTestEnv.mydomain/myWebApp";
    }
 }

为了测试,我在 META-INF 中创建了一个 beans.xml 文件:

<beans
  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_1_1.xsd"
  bean-discovery-mode="all">
    <alternatives>
      <class>myOrg.myProject.myPackage.UrlProducerTest</class>
    </alternatives>
</beans>

为了测试它,我正在做如图所示 in this blog

public class WeldContext {

    public static final WeldContext INSTANCE = new WeldContext();

    private final Weld weld;
    private final WeldContainer container;

    private WeldContext() {
        this.weld = new Weld();
        this.container = weld.initialize();
        Runtime.getRuntime().addShutdownHook(new Thread() {

            @Override
            public void run() {
                weld.shutdown();
            }
        });
    }

    public <T> T getBean(Class<T> type) {
        return container.instance().select(type).get();
    }
}

public class WeldJUnit4Runner extends BlockJUnit4ClassRunner {

    public WeldJUnit4Runner(Class<Object> clazz) throws InitializationError {
        super(clazz);
    }

    @Override
    protected Object createTest() {
        final Class<?> test = getTestClass().getJavaClass();
        return WeldContext.INSTANCE.getBean(test);
    }
}

现在,当我尝试测试逻辑时,我会这样做

@RunWith(WeldJUnit4Runner.class)
public class MyTest {
     @Inject
     UrlProducer urlProducer;         

     @Inject
     ApiFactory apiFactory;

     @Test
     public void test() {
         apiFactory.doSomethingThatRequiresUrlProducer();
     }
 }

当我运行它时,两个测试属性都被注入(inject),但我得到了 NPE,因为 apiFactory 实例中的 urlProducer 属性没有被赋值。

为什么 Weld 无法识别 ApiFactory 中的 @Inject 属性?

JDK 7、 Weld 2.2.10、Junit 4.12

更新:发布问题后,开始尝试一个更简单的全新项目(只有两个接口(interface)和三个类)。使用“独立” Weld 并没有解决问题,使用CDI-Unit确实解决了。

然后我修改了我的原始项目以使用 CDI-Unit,但它没有改进任何东西。之后,我将 ApiFactoryUrlProducerTest 的注入(inject)从字段更改为构造函数(即定义 @Inject ApiFactory(UrlProducer urlProducer) 构造函数)解决了它。我仍然没有尝试使用“独立”Weld 的解决方案(那是明天的事),但我仍然想知道为什么场注入(inject)不起作用。

最佳答案

如果UrlProducerTest是一个替代方案,你想注入(inject)这个 bean 这个类应该添加到 beans.xml进入<alternatives>标签。

编辑:

我相信,如果无法注入(inject)某些 bean,您会收到带有“不满意/不明确的依赖项”消息的异常。 Null如果您使用 CDI producer 可能会被注入(inject)返回 null 的方法,但这不是您的情况。

因此,如果控制台中没有错误,我有两个假设:

  1. 注入(inject)根本不起作用,你会得到 NPE,因为 apiFactory为空

  2. 您使用 urlProducer注入(inject)前。例如,来自构造函数或初始化 block (未提供 apiFactory.doSomethingThatRequiresUrlProducer())。所以把这个逻辑移到某个方法中,并用@PostConstruct注解

关于java - 未注入(inject)内部依赖项(Weld + JavaSE),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33102860/

相关文章:

java - 解析 JSON 时出错,但代码看起来没问题

java - 渐进式图像渲染,逐像素加载图像并在 imageLoader 中更新 ImageView

jakarta-ee - 容器找不到 .jar 中的 CDI bean(不满足的依赖项)

java - 如何在部署 WAR 文件时传递参数?

jakarta-ee - @PostConstruct之后初始化子类

java - 我可以为 EJB 使用 CDI 构造函数注入(inject)吗?

java - Weblogic消息驱动bean调用错误

java - 注入(inject)有问题

java - 除非明确注释,否则不会发现CDI bean

java - 为什么我们可以使用 Node head = null 而无需在 Java 中实例化 'head' ?