CDI:注入单个实例,但注入实例<>才不是。为什么? [英] CDI: Injecting single instance works, but injecting Instance<> does not. Why?

查看:218
本文介绍了CDI:注入单个实例,但注入实例<>才不是。为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在CDI注入的帮助下实现一些插件功能。但是我遇到了一些麻烦,并且认为我可能会从我的同伴堆叠器中得到一些外部视角: - )

I'm trying to implement somewhat of a "plugin feature" with the help of CDI injection. But i'm having some trouble and thought i might get some outside perspective from my fellow "Stackers" :-)

到目前为止,这样的事情是这样的:

I got so far that something like this works:

@Inject 
@ScoringModule("AGE")
private AgeModule ageModule;

@Inject 
@ScoringModule("CUSTOMER_TYPE")
private CustomerTypeModule customerTypeModule;

当我运行这个时,两个字段都会注入适当的实例。但是,当我尝试像这样动态注入它们时:

When i "run" this then both fields get injected with the appropriate instances. But when i try to inject them a bit more "dynamically" like this:

@Inject @Any
private Instance<CustomerScoringModule> scoringModuleInstance;

CustomerScoringModule module = scoringModuleInstance.select(new ScoringModuleLiteral("AGE")).get();

然后我会得到这样的例外:

Then i will get an exception like this:

org.jboss.weld.exceptions.UnsatisfiedResolutionException: WELD-001334: Unsatisfied dependencies for type CustomerScoringModule with qualifiers @Any @ScoringModule

这对我来说似乎很奇怪,因为CDI清楚知道我感兴趣的实例,因为直接注入打字字段是有效的。所以我假设它必须与限定符有关?不知何故CDI看到这两个实例,但决定它们都不适合我的注射请求?可能是吗?

This seems strange to me because CDI clearly "knows" about the instances i'm interested in, because the direct injection into the typed fields is working. So I'm assuming it must have something to do with the qualifiers? Somehow CDI "sees" those two instances but decides that none of them are appropiate for my injection request? could that be it?

有什么明显的可以想到我可能在这里做错了吗?我是第一次尝试使用CDI而且有可能(甚至可能)我在某处做蠢事: - )

Is there anything "obvious" that comes to mind that i might be doing wrong here? I'm trying to use CDI for the first time and it's possible (or even probable) that i'm doing something stupid somewhere :-)

任何帮助或提示都是感谢并提前多多感谢!

Any help or hint is appreciated and many thanks in advance!

下面我将附上限定符和注释文字的周围类,以供参考。

Below I'll attach the "surrounding" classes for the qualifier and the annotation literal and so forth for reference.

两个模块实现的CustomerScoringInterface:

The CustomerScoringInterface that both modules implement:

package de.otto.cccs.customerscoring.modules;

import de.otto.cccs.customerscoring.modules.vo.ScoringModuleResponseVO;
import de.otto.cccs.customerscoring.valueobjects.webservice.ScoringRequestVO;

public interface CustomerScoringModule {
    public ScoringModuleResponseVO process(ScoringRequestVO inputVO);
}

两个模块实现中的一个(它们现在只是虚拟实现而且唯一的区别是process()方法中的log.info()输出,这就是为什么我只在这里包含其中一个):

One of the two module implementations (they are just dummy implementations right now and the only difference is the log.info() output in the process() method, thats why im only including one of them here):

package de.otto.cccs.customerscoring.modules;

import javax.ejb.LocalBean;
import javax.ejb.Stateless;

import de.otto.cccs.customerscoring.modules.qualifiers.ScoringModule;
import de.otto.cccs.customerscoring.modules.vo.ScoringModuleResponseVO;
import de.otto.cccs.customerscoring.valueobjects.webservice.ScoringRequestVO;
import lombok.extern.log4j.Log4j2;

@Log4j2
@Stateless
@LocalBean
@ScoringModule("AGE")
public class AgeModule implements CustomerScoringModule {

    public AgeModule() {
        super();
    }

    @Override
    public ScoringModuleResponseVO process(ScoringRequestVO inputVO) {
        log.info("processed AGE_MODULE");

        return new ScoringModuleResponseVO();
    }

}

@ScoringModule限定符:

The @ScoringModule qualifier:

package de.otto.cccs.customerscoring.modules.qualifiers;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.inject.Qualifier;

@Qualifier
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface ScoringModule {
    String value();
}

和AnnotationLiteral:

And the AnnotationLiteral:

package de.otto.cccs.customerscoring.modules.qualifiers;

import javax.enterprise.util.AnnotationLiteral;

public class ScoringModuleLiteral extends AnnotationLiteral<ScoringModule> implements ScoringModule {

    private static final long serialVersionUID = 1L;
    private String value;

    public ScoringModuleLiteral(String value) {
        this.value = value;
    }

    @Override
    public String value() {
        return this.value;
    }
}

最后我的空beans.xml:

And finally my empty beans.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>


推荐答案

我最终将模块从EJB更改为普通Java课程和我所有的麻烦都消失了。

I ended up changing the modules from EJB's to plain Java classes and all my troubles went away.

我真的不需要将模块作为EJB,我只是错误地假设他们必须通过初始注入CDI,不再是这种情况了(旧的J2EE版本也是如此)

I didn't really need the modules to be EJB's i just wrongly assumed in the beginnig that they had to be to be injected via CDI, which is not the case anymore (it was true with older J2EE releases)

感谢您的反馈!

这篇关于CDI:注入单个实例,但注入实例&lt;&gt;才不是。为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆