有没有办法要求Weld SE在给定时间注入特定的实现?

时间:2014-12-23 14:58:35

标签: weld

我在一个应用程序中使用Weld SE,在我的应用程序中,我有一个接口,我有3个实现,但这会导致Weld模糊不清。据我所知,焊接歧义解决技术是静态的,这可以通过以下方式完成:@specialize,@ alt,@ Name或使用限定符。但这对我没有帮助。我需要为每种情况指定一个给定的接口类实现。

我无法找到符合我要求的解决方案。

这是一个代表我的观点的代码

public class Foo {
    @Inject
    MyInterface target;
    public void doSomething() {
        target.doIt();
    }
}

public class Bar1 implements MyInterface {    
    public void doIt() {
        System.out.println("Hello");
    }
}

public class Bar2 implements MyInterface {  
    public void doIt() {
        System.out.println("Goodbye");
    }

}


public class FooMain {
    public static void main(String[] args) {
        Weld weld = new Weld();
        final WeldContainer container = weld.initialize();
        Foo foo1 = container.instance().select(Foo.class).get();
        Foo foo2 = container.instance().select(Foo.class).get();
    }
}

此代码导致此异常:

Exception in thread "main" org.jboss.weld.exceptions.DeploymentException: WELD-001409: Ambiguous dependencies for type MyInterface with qualifiers @Default
  at injection point [BackedAnnotatedField] @Inject com.lodh.arte.test.cdi.Foo.target
  at com.lodh.arte.test.cdi.Foo.target(Foo.java:0)
  Possible dependencies: 
  - Managed Bean [class com.lodh.arte.test.cdi.Bar2] with qualifiers [@Any @Default],
  - Managed Bean [class com.lodh.arte.test.cdi.Bar1] with qualifiers [@Any @Default]

我需要动态告诉Weld哪个实现用于注入,就像在这个假想的方法中一样Weld.use:

 Weld.use ( MyInterface.class, Bar1.class);
 Foo foo1 = container.instance().select(Foo.class).get();
 Weld.use ( MyInterface.class, Bar2.class);
 Foo foo2 = container.instance().select(Foo.class).get();

感谢您的帮助

此致

纳德

1 个答案:

答案 0 :(得分:1)

首先,您有两个MyInterface的实现。 Bar1Bar2。焊接时不知道在注入MyInterface时要选择哪个实现,因此它会抛出这个"不明确的依赖关系"错误。 为避免此错误,您应该为实现提供不同的限定符。

您必须首先验证您的实施:

@MyQualifier1
public class Bar1 implements MyInterface {
(...)
}

@MyQualifier2
public class Bar2 implements MyInterface {
(...)
}

这将允许注入这样的特定实现:

@Inject
@MyQualifier1
MyInterface target;

现在,您正在注册MyInterface符合@MyQualifier1的资格。在运行时,在这种情况下,其类型将为Bar1

另一种方法是,如果您想在运行时决定使用Instance所需的实现:

@Inject
Instance<MyInterface> unqualifiedInstance;

void do(){
    /// first attach the qualifier, we missed at the injection-point:
    Instance qualifiedInstance = instance.select(new AnnotationLiteral<MyQualifier2>(){})
    /// Now you have a qualified Instance, which is a new Object without touching the unqualifiedInstance!
    MyInterface target = qualifiedInstance.get();
    /// so you can decide which implementation you need by passing the qualifier per select-method. in this case its bar2
    target.doIt();
}

如果您需要有关限定符的进一步帮助,您可以找到焊接文档,尤其是第4.3章及以下内容。 http://docs.jboss.org/weld/reference/latest/en-US/html/injection.html