Можно ли внедрить реализацию EJB, а не его интерфейс, используя CDI?
Моя конфигурация: Wildfly 8.2.0, Weld
Можно ли вводить в bean-компоненте, а не в его интерфейсе в CDI?
@Stateless
class Bean implements IBean {
...
}
interface IBean {
...
}
@SessionScoped
class Scoped {
@Inject
Bean bean; //Fail
@Inject
IBean iBean; //OK
}
РЕДАКТИРОВАТЬ:
Больше информации в моем предыдущем вопросе: EJB без сохранения состояния внедряет интерфейсный сбой
2 ответа
Да, вы можете, но когда EJB внедряет бизнес-представление, единственное представляемое вами бизнес-представление - это @Local
посмотреть, который является по умолчанию при реализации интерфейса (IBean
в вашем случае это локальный бизнес интерфейс). Итак, если вы хотите внедрить сам компонент, вам нужно сообщить контейнеру, что вы используете представление без интерфейса.
В вашем примере, если вы все еще хотите реализовать свой интерфейс и внедрить Bean
Вы должны использовать @LocalBean
аннотация, которая означает, что бин предоставляет представление без интерфейса:
@Stateless
@LocalBean // <-- no-interface view
class Bean implements IBean {
...
}
interface IBean {
....
}
@SessionScoped
class Scoped {
@Inject
Bean bean; //Should be OK
}
Или, если вы не хотите реализовывать какой-либо интерфейс, компонент по умолчанию определяет представление без интерфейса:
@Stateless
class Bean {
...
}
@SessionScoped
class Scoped {
@Inject
Bean bean; //OK
}
Смотрите также:
Похоже, вы получили неясный ответ на свой предыдущий вопрос, и на самом деле весь этот вопрос является продолжением этого вопроса.
Вообще говоря, CDI позволяет вводить как интерфейс, так и impl для управляемых компонентов CDI. Это не относится к EJB. Когда EJB реализует интерфейс, это становится его бизнес-интерфейсом. Действительными являются только объявленные там методы. Эффективно, ваш Bean
Класс определяет только то, как эти методы работают, и фактически не существует как компонент в вашей среде выполнения.
Так что нет, при использовании EJB вы не можете внедрить реализацию, только интерфейс. Если вы действительно хотите это сделать, я бы отошел от EJB.
Одна из возможных причин, по которой вы можете не захотеть использовать интерфейс для внедрения EJB, может заключаться в том, что у вас может быть много EJB, реализующих этот интерфейс, и ваш контейнер EJB может жаловаться на то, что он не может разрешить двусмысленность того, какой конкретный EJB должен быть введенным в данном контексте. Если это так, вы можете легко указать имя конкретного класса EJB, реализующего общий интерфейс, используяjavax.inject.Named
аннотация, как показано ниже:
@SessionScoped
class Scoped {
@Named("Bean")
IBean iBean;
}