没有注入内部依赖(Weld + JavaSE)

时间:2015-10-13 12:34:17

标签: 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";
    }
 }

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

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

当我运行它时,两个测试属性都是注入,但我得到了NPE,因为urlProducer实例中的apiFactory属性尚未赋值。

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

JDK 7,Weld 2.2.10,Junit 4.12

更新:发布问题后,开始尝试使用更简单的全新项目(只有两个接口和三个类)。使用Weld&#34; standalone&#34;没有解决问题,使用CDI-Unit解决了它。

然后我修改了我的原始项目以使用CDI-Unit,但它没有改进任何东西。之后,我将UrlProducerTestApiFactory的注入从字段更改为构造函数(即定义@Inject ApiFactory(UrlProducer urlProducer)构造函数)解决了它。我仍然没有尝试使用&#34; standalone&#34;焊接(即明天),但我仍然有兴趣知道为什么现场注射不起作用。

2 个答案:

答案 0 :(得分:1)

如果UrlProducerTest是另一种选择,并且您想要注入此bean,则应将此类添加到beans.xml<alternatives>标记中。

修改

我相信如果一些豆子不能被注射,你就会因为不满足/不明确的依赖关系而得到例外。信息。如果您使用返回null的CDI Null方法,则可以注入producer,但这不是您的方案。

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

  1. 注射完全不起作用,因为apiFactory为空

  2. 而获得NPE
  3. 您在注射前使用urlProducer。例如,从构造函数或初始化块(未提供apiFactory.doSomethingThatRequiresUrlProducer())。因此,将此逻辑移至某个方法并通过@PostConstruct

  4. 进行注释

答案 1 :(得分:0)

因为ApiFactorySp不是CDI bean。您需要使用@Named对类进行批注,以将该类标识为CDI以便CDI执行依赖项注入。