繁体   English   中英

Java ee接口条件注入

[英]Java ee interface conditional inject

我有以下界面:

public interface ResultEvaluationInterface {
    public void evaluateResults(Event e);
}

我想根据我的Event.type注入我的类,具有相同实现的不同类。 像这样的东西:

@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.");
        }
    }

}

ResultEvaluationRunningEJBResultEvaluationSwimmingEJB都实现了该接口。 有人知道如何以一种好的方式做到这一点吗?

如果你真的想使用硬编码if语句在prod和dev事件之间切换,你可以使用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) {
       ...
   }
}

而不是在一个带有巨型开关语句的调度程序中注入20-30。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM