Java ee接口条件注入
Java ee interface conditional inject
我有以下界面:
public interface ResultEvaluationInterface {
public void evaluateResults(Event e);
}
并且我想根据我的 Event.type
不同的 class 注入我的 class 和相同的实现。类似的东西:
@Stateless
@LocalBean
public class ResultEvaluation implements ResultEvaluationInterface {
@Override
public void evaluateResults(Event e) {
switch (e.getType()) {
case Type.Running:
// inject and call ResultEvaluationRunningEJB.evaluateResults(e)
case Type.Swimming:
// inject and call ResultEvaluationSwimmingEJB.evaluateResults(e)
default:
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
ResultEvaluationRunningEJB
和 ResultEvaluationSwimmingEJB
都实现了接口。有人知道如何以好的方式做到这一点吗?
如果您真的想使用硬编码的 if 语句在生产事件和开发事件之间切换,您可以使用 CDI 限定符,只需将这两个实现注入 Facade:
@Stateless
@LocalBean
public class ResultEvaluationFacade {
@Inject
@Development
private ResultEvalutationInterface dev;
@Inject
@Production
private ResultEvalutionInterface prod;
@Override
public void evaluateResults(Event e) {
switch (e.getType()) {
case Type.Production:
prod.evaluteResult(e);
break;
case Type.Development:
dev.evaluteResult(e);
break;
default:
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
并定义您的两个实现:
@Development
public class ResultEvaluationDevelopment implements ResultEvaluationInterface {
...
}
@Production
public class ResultEvaluationDevelopment implements ResultEvaluationInterface {
...
}
但是我会考虑使用模拟 Maven 项目来容纳两个单独的实现。
或者你可以使用不同的 CDI 事件类型,像这样。
public void observeDevEvent(@Observe DevEvent event) {
//do stuff.
}
public void observeProdEvent(@Observe ProdEvent event) {
//do stuff
}
触发事件看起来像这样:
@Inject
private Event<ProdEvent> prodEvent;
public void someMethod() {
ProdEvent pe = new ProdEvent()
// set some data on ProdEvent
prodEvent.fire(pe);
}
注意事件也可以与限定符一起使用,因此您还可以向事件添加限定符注释,而不是实现两种不同类型的事件。
@Inject
@Production
private Event<MyEvent> event;
并监听@Prodcution 事件;
public void handleProdEvent(@Observer @Production MyEvent myEvent) {
// do Stuff.
}
对于 bean 的惰性实例化,您可以使用 CDI 实例注入。
@Inject
private Instance<BeanA> beanA;
....
public void doStuff(Event e) {
...
case Type.Production:
//lazily evaluates and instantiatiates bean.
beanA.get().evaluateResult(e);
}
注意:我还没有确认这是否有效,但你应该可以用它来解决问题。
您可以使用动态 CDI 事件调度:
public class EventDispatcher {
@Inject
BeanManager beanManager;
public void handle(MyEvents mytype) {
beanManager.fireEvent(mytype, mytype.getQualifiyer());
}
}
您可以在您的事件枚举中引用您的限定符,如下所示:
public enum MyEvents {
EVENTA(new EventA() {
@Override
public Class<? extends Annotation> annotationType() {
return this.getClass();
}
}),
EVENTB (new EventB() {
@Override
public Class<? extends Annotation> annotationType() {
return this.getClass();
}
});
private final Annotation annotation;
MyEvents(Annotation annotation) {
this.annotation = annotation;
}
public Annotation getQualifiyer() {
return annotation;
}
};
预选赛看起来像这样:
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER,ElementType.FIELD})
public @interface EventA {
}
这样您就可以简单地将观察者方法添加到事件处理 bean 中:
public class EventProcessorA {
...
public void handleEvent(@Observer @BeanA MyEvents myevent) {
...
}
}
而不是使用巨大的 switch 语句在一个调度程序中注入 20-30。
我有以下界面:
public interface ResultEvaluationInterface {
public void evaluateResults(Event e);
}
并且我想根据我的 Event.type
不同的 class 注入我的 class 和相同的实现。类似的东西:
@Stateless
@LocalBean
public class ResultEvaluation implements ResultEvaluationInterface {
@Override
public void evaluateResults(Event e) {
switch (e.getType()) {
case Type.Running:
// inject and call ResultEvaluationRunningEJB.evaluateResults(e)
case Type.Swimming:
// inject and call ResultEvaluationSwimmingEJB.evaluateResults(e)
default:
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
ResultEvaluationRunningEJB
和 ResultEvaluationSwimmingEJB
都实现了接口。有人知道如何以好的方式做到这一点吗?
如果您真的想使用硬编码的 if 语句在生产事件和开发事件之间切换,您可以使用 CDI 限定符,只需将这两个实现注入 Facade:
@Stateless
@LocalBean
public class ResultEvaluationFacade {
@Inject
@Development
private ResultEvalutationInterface dev;
@Inject
@Production
private ResultEvalutionInterface prod;
@Override
public void evaluateResults(Event e) {
switch (e.getType()) {
case Type.Production:
prod.evaluteResult(e);
break;
case Type.Development:
dev.evaluteResult(e);
break;
default:
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
并定义您的两个实现:
@Development
public class ResultEvaluationDevelopment implements ResultEvaluationInterface {
...
}
@Production
public class ResultEvaluationDevelopment implements ResultEvaluationInterface {
...
}
但是我会考虑使用模拟 Maven 项目来容纳两个单独的实现。
或者你可以使用不同的 CDI 事件类型,像这样。
public void observeDevEvent(@Observe DevEvent event) {
//do stuff.
}
public void observeProdEvent(@Observe ProdEvent event) {
//do stuff
}
触发事件看起来像这样:
@Inject
private Event<ProdEvent> prodEvent;
public void someMethod() {
ProdEvent pe = new ProdEvent()
// set some data on ProdEvent
prodEvent.fire(pe);
}
注意事件也可以与限定符一起使用,因此您还可以向事件添加限定符注释,而不是实现两种不同类型的事件。
@Inject
@Production
private Event<MyEvent> event;
并监听@Prodcution 事件;
public void handleProdEvent(@Observer @Production MyEvent myEvent) {
// do Stuff.
}
对于 bean 的惰性实例化,您可以使用 CDI 实例注入。
@Inject
private Instance<BeanA> beanA;
....
public void doStuff(Event e) {
...
case Type.Production:
//lazily evaluates and instantiatiates bean.
beanA.get().evaluateResult(e);
}
注意:我还没有确认这是否有效,但你应该可以用它来解决问题。
您可以使用动态 CDI 事件调度:
public class EventDispatcher {
@Inject
BeanManager beanManager;
public void handle(MyEvents mytype) {
beanManager.fireEvent(mytype, mytype.getQualifiyer());
}
}
您可以在您的事件枚举中引用您的限定符,如下所示:
public enum MyEvents {
EVENTA(new EventA() {
@Override
public Class<? extends Annotation> annotationType() {
return this.getClass();
}
}),
EVENTB (new EventB() {
@Override
public Class<? extends Annotation> annotationType() {
return this.getClass();
}
});
private final Annotation annotation;
MyEvents(Annotation annotation) {
this.annotation = annotation;
}
public Annotation getQualifiyer() {
return annotation;
}
};
预选赛看起来像这样:
@Qualifier
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER,ElementType.FIELD})
public @interface EventA {
}
这样您就可以简单地将观察者方法添加到事件处理 bean 中:
public class EventProcessorA {
...
public void handleEvent(@Observer @BeanA MyEvents myevent) {
...
}
}
而不是使用巨大的 switch 语句在一个调度程序中注入 20-30。