CDI:注入单个实例,但注入实例<>才不是。为什么呢?

时间:2017-08-16 11:56:56

标签: java-ee cdi payara

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

我到目前为止这样的事情有效:

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

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

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

@Inject @Any
private Instance<CustomerScoringModule> scoringModuleInstance;

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

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

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

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

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

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

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

两个模块实施的CustomerScoringInterface:

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()输出,这就是为什么我只在这里包含其中一个):

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限定符:

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:

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:

<?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>

1 个答案:

答案 0 :(得分:0)

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

我并不是真的需要这些模块成为EJB,并且在初学者中错误地认为它们必须通过CDI注入,而现在不再是这种情况了(旧的J2EE也是如此)版本)

感谢您的反馈!