上下文
基于我的Java EE应用程序接收的XML,我想创建一个新的AreeConfiguration对象,其中发生3个对象的注入。选择正确的实例<>基于此XML中的信息发生。因此,我传递了这个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&lt;&gt;。
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 only working for POJOs created by CDI container?
答案 0 :(得分: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。
答案 1 :(得分: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);
...
}
答案 2 :(得分:0)
您通常是正确的,最多可以将一些有限的数据类型传递给CDI来创建对象 - 即基本体,静态类型,字符串,枚举到您的限定符中。这是注释的限制。我对你的结构不太了解的一件事是客户将所有这些传递给你。这使您的代码更加脆弱,客户端和服务器更加紧密耦合。难道你不能传递一些代表某种配置的ID吗?您仍然存在无法传递XML元素的问题。你可以传递一个字符串,并在生产者方法的InjectionPoint中使用它。