Java EE 6 и CDI - PullRequest
       39

Java EE 6 и CDI

9 голосов
/ 28 июля 2011

Я только начинаю изучать CDI и Java EE 6, но я нашел этот фрагмент кода, который хочу полностью понять.

@Stateful
@Model
public class MemberRegistration {
   @Inject
   private EntityManager em;

   @Inject
   private Event<Member> memberEventSrc;

   private Member newMember;

   @Produces
   @Named
   public Member getNewMember() {
      return newMember;
   }
}

Затем ... я увидел, что страница jsf ссылается на эту newMember объект, подобный этому:

<h:inputText value=#{newMember.name}/>

Итак, мой вопрос: не имеет значения, если я добавлю аннотацию @Named внутри переменной какого-либо объекта, она все равно будет доступна из кода JSF?Кроме того, что в этом случае использует @Produces, и, наконец, @Stateful предпочтительнее, чем @Stateless в Java EE 6?Если это так, почему?

1 Ответ

19 голосов
/ 28 июля 2011

Несмотря на свою простоту, этот бин действительно многое делает;)

Либо аннотация @Named (CDI), либо @ManagedBean (нативная для JSF) необходима для того, чтобы bean-компонент был известен JSF. Тем не менее, Java EE имеет концепцию stereotypes, которая является разновидностью составных аннотаций, объединяющих ряд других.

В данном случае @ Model - это такой стереотип, он объединяет @Named и @RequestScoped.

@Produces аннотирует фабричный метод; метод, который знает, где взять экземпляр некоторого типа. Его можно комбинировать с так называемой аннотацией квалификатора, например, @Foo, после чего вы можете использовать эту аннотацию для добавления чего-либо в некоторый компонент. Однако в этом случае он объединяется с @Named, что делает JSF доступным newMember. Вместо создания бина, как это было бы, например, когда bean-компонент @RequestScoped встречается первым, под прикрытием метод getNewMember() будет вызываться, когда JSF хочет экземпляр. См. Внедрение зависимостей в Java EE 6 для получения дополнительной информации.

@Stateful обычно не предпочтительнее, чем @Stateless, когда используется автономно. @Stateless бины объединяются и выполняют один метод для клиента (обычно в транзакционном контексте). Их коллега с состоянием не объединяется, и без CDI вызывающая сторона должна отслеживать его жизненный цикл (в конечном итоге вызывая аннотированный метод @Remove). Здесь бину также назначается область действия (запрос, через @Model), поэтому об этом позаботится контейнер.

Вероятная причина для использования этой аннотации здесь, вероятно, состоит в том, чтобы сделать методы бина транзакционными. Хотя приведенный фрагмент не показывает его использования, я думаю, что есть версия этого класса с большим количеством методов, использующих EntityManager. Транзакции вступят в игру там.

(Обратите внимание, что объединение аннотаций таким способом дает разработчику Java EE много возможностей, но в одном бине он вызывает некоторые опасения, что противоречит мантре о том, что бин должен делать одно и делать это хорошо. альтернатива - аннотированный компонент @Model, фокусирующийся только на проблемах представления, который внедряется с компонентами @Stateless, которые инкапсулируют бизнес-логику вместо EntityManager.)

...