2015-07-17 7 views
2

У меня есть следующий интерфейс:Java EE интерфейс условных инъекционные

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 как реализовать интерфейс. У кого-то есть хорошая идея, как это сделать в хорошем смысле?

+0

Для того, чтобы получить это прямо, вы хотите использовать реализацию макета для среды разработки? – dngfng

+0

Использует ли «Производство» и «Разработка» ваш развернутый экземпляр, т. Е. У вас есть производственный экземпляр, который будет получать только события «Производство», или может ли один установленный экземпляр когда-либо получать события «Развертывание» и «Производство»? – user140547

+0

Тип был просто примером. Я изменю их, чтобы не смутить вас. – perotom

ответ

2

Если вы действительно хотите использовать жёстко, если заявление для переключения между Prod и Дев событий, которые вы могли бы использовать CDI Отборочные просто впрыснуть две реализации в Фасад:

@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 { 
    ... 
} 

Однако я бы предпочел использовать проект mock 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); 
} 

Примечание событие может также работать с отборочным, так что вы можете также добавить аннотацию Qualifier в событие вместо реализации два различных типов события ,

@Inject 
@Production 
private Event<MyEvent> event; 

И слушать события @Prodcution;

public void handleProdEvent(@Observer @Production MyEvent myEvent) { 
    // do Stuff. 
} 

Для ленивого создания бобы вы можете использовать инъекцию инсулина CDI.

@Inject 
private Instance<BeanA> beanA; 

.... 

public void doStuff(Event e) { 
    ... 
    case Type.Production: 
      //lazily evaluates and instantiatiates bean. 
      beanA.get().evaluateResult(e); 
} 
+0

. Я считаю, что ваш первый пример соответствует моим требованиям, а именно еще один вопрос: если я добавлю намного больше компонентов для инъекций, этот интерфейс (20-30) и добавить его в ResultEvaluationFacade, не так ли плохо для производительности? особенно если я использую событие PostConstruct с взаимодействием с базой данных, например, с помощью ResultEvaluationDevelopment? – perotom

+1

В таком secenario я бы не использовал эту технику. Чтобы справиться с проблемами производительности, вы можете использовать экземпляр , это эффективно разрешает ленивую загрузку и активацию бобов. См. Мой расширенный ответ. – dngfng

+0

Какую технику вы бы использовали? Очень полезно ответить! – perotom

0

Примечание: Я не подтвердил, что это работает, но вы должны иметь возможность работать с этим.

Вы можете использовать динамическое событие 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 { 

} 

Таким образом, вы можете просто добавить методы наблюдения к событиям поющие бобы:

public class EventProcessorA { 
    ... 
    public void handleEvent(@Observer @BeanA MyEvents myevent) { 
     ... 
    } 
} 

Вместо того, чтобы вводить 20-30 в один диспетчер с гигантским оператором переключения.

Смежные вопросы