4

我有一个工厂班

@ApplicationScoped /* 'ApplicationScoped' is not a must */
class MyFactory {

   @Inject
   private IService aService;

   ...
}

和一个 JAXB 注释类

@XmlRootElement(name = "item")
class AnItem {

  @Inject
  MyFactory myFactory;

  ...
}

AnItem由 JAXB 从 XML 文件实例化。问题myFactorynull。如果我将其替换为

...
MyFactory myFactory = new MyFactory();
...

然后myFactory.aService为空。

如何在 JAXB 创建的类中使用依赖注入?

4

3 回答 3

3

以下解决方案受到Adam Warski 的启发,另请参阅BeanManager Javadoc

首先,我需要两个实用方法:

import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.naming.InitialContext;
import javax.naming.NamingException;

public class Utils {
  public static BeanManager getBeanManager() {
    try {
        InitialContext initialContext = new InitialContext();
        return (BeanManager) initialContext.lookup("java:comp/BeanManager");
    } catch (NamingException e) {
        throw new RuntimeException("Failed to retrieve BeanManager!", e);
    }
  }

  public static <T> T getBean(Class<T> c) {
    T result = null;
    BeanManager bm = getBeanManager();
    Set<Bean<?>> beans = bm.getBeans(c);
    if (! beans.isEmpty()) {
        Bean<?> bean = beans.iterator().next();
        result = c.cast(bm.getReference(bean, c, bm.createCreationalContext(bean)));
    }
    return result;
  }
}

AnItem然后必须像这样更改类:

@XmlRootElement(name = "item")
class AnItem {

  MyFactory myFactory = Utils.getBean(MyFactory.class);

  ...
}
于 2013-07-05T09:45:40.810 回答
2

我认为您在错误的类中有一些代码,这导致依赖关系以错误的方式出现,这反过来又使对象难以正确构造。

Item看起来像一个的类(有时称为实体)。Newable 类不是由您的容器创建的,而是由服务类创建的。Jaxb 是服务的一个示例。服务类由您的 DI 容器创建。

我会重新评估您是否需要Item持有对myFactory. 您没有在问题中显示这一点,但必须有一种方法Item可以调用myFactory.

这段代码应该移出Item到一个不同的类(可能是一个新的服务)中,它接受一个item作为参数。

于 2013-07-07T04:10:47.447 回答
0

CDI bean 应该是容器管理的,这意味着如果您使用new创建它们,您将不会获得任何容器服务(注入、拦截、装饰器等)。您需要@Inject工厂类才能使注入正常工作。

于 2013-07-05T14:37:01.903 回答