2016-05-15 3 views
1

Вопрос в целом заключается в том, что CDI-инъекция работает, когда CDI-компонент создается через поле производителя в службе JAX-RS (WAR-файл), пока его потребление внутри EJB bean (EJB-файл)?CDI Injection in EJB от WAR не сохраняет оригинальный объект

На основании этого вопроса Is it possible to @Inject a @RequestScoped bean into a @Stateless EJB? такой сценарий должен работать, но я не могу заставить это работать.

Вот некоторые подробности. Я очень простое приложение JavaEE (https://github.com/kocherovms/develorium.com/tree/master/cdi_problem) со следующей структурой:

hello-ear: 
| 
+- hello-ejb 
| | 
| +- HelloBean 
| 
+- hello-war 
    | 
    +- HelloService 

В этом приложении я пытаюсь пройти через КДИ инъекции в Guest объект между службой JAX-RS (привет войны) и EJB боба (привет-EJB). Вот служба JAX-RS, который производит экземпляр Guest объекта:

@Path("/hello") 
public class HelloService { 
    @EJB 
    private Hello hello; 

    @Produces 
    @RequestScoped 
    @GuestMarker 
    private Guest guest; 

    @GET 
    public Response perform() { 
     guest = new Guest(); 
     guest.setName("white rabbit"); 
     String text = hello.getHelloText(); 
     return Response.ok().type(MediaType.TEXT_PLAIN).entity(text).build(); 
    } 
} 

Реализация Hello от HELLO-EJB пытается потреблять Guest объект через КДИ @Inject:

@Stateless 
public class HelloBean implements Hello { 
    @Inject 
    @GuestMarker 
    Guest guest; 

    @Override 
    public String getHelloText() { 
     return String.format("Hello, %s!\n", guest.getName()); 
    } 
} 

Я развертывание этого приложения на сервере WildFly 10. Само развертывание отлично работает, и мой сервис работает. Однако вызов службы (curl http://localhost:8080/hello) всегда возвращает 'Hello, null!' вместо «Привет, белый кролик!».

Это означает, что объект Guest производится на стороне HelloService не доступен в пределах HelloBean и по умолчанию построено используются Guest экземпляра. Я пробовал различные области (например, SessionScoped, ApplicationScoped), попытался использовать метод продюсера, попробовал сделать bean-компонентом для состояния и даже singleton. Ничего не работает. Кажется, CDI всегда использует область Dependant для моего случая.

Возможно ли передать экземпляр объекта Guest с HelloService на номер HelloBean?

+0

Нет необходимости в том, чтобы эти два 'гостя' были одним и тем же экземпляром. Измените аннотацию '@ Produces' на' @ Inject', тогда контейнер * МОЖЕТ * ввести тот же экземпляр для EJB и ресурса JAX-RS. –

+0

Привет, Цзинь. Изменение '@ Produces' ->' @ Inject' - это не то, что мне нужно. Мне нужно, чтобы тот же компонент в '@ Produces' в JAX-RS (HelloService) был доступен в точке вставки в EJB (HelloBean). Делая это, я хочу передать некоторую контекстную информацию от JAX-RS до EJB. –

ответ

0

Я думаю, что вы, возможно, слишком усложняете настройку. Поля производителей оцениваются один раз, поэтому факт, что вы мутируете это, является проблемой. Ваш производитель должен выглядеть

@Produces 
@RequestScoped 
@GuestMarker 
private Guest guest = new Guest(); 

А потом просто вызовите сеттер в методе JAX-RS, вместо инстанцировании его. Но это не решит вашу проблему, теперь, когда я понимаю, что вы используете EAR. Объем CDI-компонентов находится внутри связанного модуля. Таким образом, EJB - это собственный контекст, не используемый вашим ресурсом JAX-RS.

+0

Джон, кажется, вы правы в отношении совместного использования контекста. После того, как я переместил HelloBean в файл войны (рядом с HelloService), проблема исчезла. В любом случае вы можете указать мне, где я мог бы прочитать о видимости бисов CDI, связанных с моей проблемой? Спасибо! –

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