代码之家  ›  专栏  ›  技术社区  ›  perotom

Java ee接口条件注入

  •  3
  • perotom  · 技术社区  · 11 年前

    我有以下界面:

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

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

    2 回复  |  直到 9 年前
        1
  •  2
  •   dngfng    11 年前

    如果您真的想使用硬编码的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;
    

    倾听“生产”事件;

    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);
    }
    
        2
  •  0
  •   dngfng    11 年前

    注意:我还没有确认这是否有效,但你应该能够用它解决一些问题。

    您可以使用动态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个巨大的switch语句。

    推荐文章