3

语境:

基于我的 Java EE 应用程序接收到的 XML,我想创建一个新的 AreeConfiguration 对象,其中发生 3 个对象的注入。根据此 XML 中的信息选择正确的 Instance<>。因此,我从这个 XML 传递信息。

我有一个数据结构,应该在运行时填充这些 AreeConfiguration 对象:

private HashMap<Integer, AreeConfiguration> configurations = new HashMap<Integer, AreeConfiguration>();

public void parseNewConfiguration(Element el) throws InvalidDescriptorException {
    if(!isValidConfiguration(el)) throw new InvalidDescriptorException();

    int key = getUniqueKey();

    AreeConfiguration cfg = new AreeConfiguration(key, el);       
    configurations.put(key, cfg);
}

我的 AreeConfiguration 对象应该(理想情况下)用基本的 XML 信息构造并注入一些对象。稍后,我想使用 XML 中的信息来选择正确的 Instance<>。

public class AreeConfiguration {

@Inject
private Instance<AreeInput> ais;
private AreeInput ai;

@Inject
private Instance<AreeReasoner> ars;
private AreeReasoner ar;

@Inject
private Instance<AreeOutput> aos;
private AreeOutput ao;

AreeConfiguration(int key, Element el) throws InvalidDescriptorException {
    ...
}   

@PostConstruct
public void chooseComponents(){     
    ai = chooseInput();
    ar = chooseReasoner();
    ao = chooseOutput();
}

我发现并尝试过的:

通过研究(在 Stack Overflow),我现在了解到 CDI 不会注入使用new Object(). 上面显示的代码,从不输入chooseComponents()

当我想尝试使用@Producer 时,我会使用注释parseNewConfiguration(Element el)@Producer添加一个@New AreeConfiguration cfg参数。但是,我也不能通过Element el,这很不幸,因为它包含基本的 XML 信息。

如果我没有彻底解释自己,请提出其他问题。我正在寻找一种使用 CDI 完成上述任务的方法。

此外,这个问题的答案中提出的解决方案有多“干净”:@Inject 仅适用于由 CDI 容器创建的 POJO?

4

3 回答 3

1

要对不是由 CDI 容器创建的实例执行注入,并且您可以访问 BeanManager,那么您可以执行以下操作:

// Create a creational context from the BeanManager
CreationalContext creationalContext = beanManager.createCreationalContext(null);

// Create an injection target with the Type of the instance we need to inject into
InjectionTarget injectionTarget = beanManager.createInjectionTarget(beanManager.createAnnotatedType(instance.getClass()));

// Perform injection into the instance
injectionTarget.inject(instance, creationalContext);

// Call PostConstruct on instance
injectionTarget.postConstruct(instance);

可用于完成所有工作的类的示例位于:http ://seamframework.org/Documentation/HowDoIDoNoncontextualInjectionForAThirdpartyFramework 。

于 2013-04-22T13:03:59.007 回答
1

在这种特殊情况下,动态注入只需要在客户端调用之后进行。因此,我现在只是在我的 WebService 中注入我需要的东西。当客户端调用 WebService 时,会自动进行注入。

@Path("newconfiguration")
@RequestScoped
public class NewConfigurationResource {

@Context
private UriInfo context;

@Inject
private AreeConfiguration injConfig;

public NewConfigurationResource() { }

@POST
@Path("post")
@Produces("application/json")
public Response postJson() {
    ...
    doSomething(injConfig);
    ...
} 
于 2013-05-06T01:39:33.870 回答
0

您通常是正确的,您最多可以将一些有限的数据类型传递给 CDI 以创建对象 - 即原语、静态类型、字符串、枚举到您的限定符中。这是注释的限制。我不太了解您的结构的一件事是为什么客户将所有这些都传递给您。这使您的代码更加脆弱,客户端和服务器的耦合更加紧密。你不能传递一些代表某种配置的 ID 吗?您仍然遇到无法传递 XML 元素的问题。您可以传递一个字符串并在生产者方法的 InjectionPoint 中使用该字符串。

于 2013-04-21T20:51:57.017 回答