如何在JAXB unmarshalled对象中使用依赖注入?

时间:2013-07-03 16:58:18

标签: java dependency-injection jaxb cdi

我有一个工厂类

@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创建的类中使用依赖注入?

3 个答案:

答案 0 :(得分:2)

以下解决方案的灵感来自Block of 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);

  ...
}

答案 1 :(得分:2)

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

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

我会重新评估您是否需要Item持有对myFactory的引用。您未在问题中显示此内容,但Item中必须有一个方法可以调用myFactory中的内容。

此代码应从Item移出到另一个接受item作为参数的类(可能是新服务)。

答案 2 :(得分:0)

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