您的意思是:“取决于配置...”您何时决定使用什么?在编译时还是运行时?
有几种方法可以做到这一点:
1. @Alternative 和 beans.xml
使用 @Alternative 注释 SomeService 和 OtherService 并在 beans.xml 中使用
再次激活其中一个
<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">
<alternatives>
<class>SomeService</class>
</alternatives>
</beans>
2。有资格赛和制片人:
@Qualifier
@Retention(RUNTIME)
@Target({TYPE, METHOD, FIELD, PARAMETER})
public @interface First {}
并用以下方式注释两个 Bean:
@First
@Stateless
public SomeService{ ... }
现在您可以拥有如下所示的 Producer-Class:
@Dependent
public class ServiceProducer {
@Inject
@First
private Service someService;
@Inject
@Second
private Service otherService;
@Produces
@Default
public Service getService() {
switch (someCondition) {
case SOME:
return someService;
case OTHER:
return otherService;
default:
return null;
}
}
}
最后将 Service 注入到你想使用的地方:
@Inject
Service service;
3.没有 Producer 但有 Qualifier-Annotations
您需要注释 SomeService 和 OtherService 才能使其工作。
@Inject
Instance<Service> services;
public void someBussinessMethod(){
Annotation qualifier = someCondition ? new AnnotationLiteral<First>() {} : new AnnotationLiteral<Second>() {};
Service s = services.select(qualifier).get();
}
4.没有限定符
在我看来,这是最丑陋和最慢的解决方案,但您可以迭代 Injectend 服务并由 Class 决定是否要使用它。
@Inject
Instance<Service> services;
public void doSomething() {
Class clazz = someCondition ? SomeService.class : OtherService.class;
Service first = services.stream().filter(s -> s.getClass() == clazz).findFirst().get();
}
可以在这里找到详细的解释:
https://docs.jboss.org/cdi/learn/userguide/CDI-user-guide.html#injection