2016-03-30 4 views
1

В CDI я могу вставлять bean-компонент с определенной областью, сфера, с которой был определен класс bean-компонента. Но что, если я создаю класс bean без какой-либо области, и я даю возможность этому компоненту в точке инъекции. Мое требование состоит в том, чтобы в последнем случае сделать возможной оценку времени впрыска. Проблема в том, что инъекция происходит с dependent scope вместо желаемого аннотированного объема, если я не использую producer.В CDI, как задать область для боба в точке инъекции?

Например:

Случай 1:

Когда я объявить объем боба в своем объявлении класса следующим образом:

@ApplicationScoped 
class UserDetails { 
... 
} 

и вводили следующим образом:

@ViewScoped 
class UserView { 

    @Inject 
    UserDetails userDetails; 
    . 
    . 
} 

Работает так, как ожидалось. Боб, введенный в область применения, доступен во всем приложении во всех других компонентах.


СЛУЧАЙ 2:

Но когда я не дают рамки в объявлении класса:

class UserDetails { 
... 
} 

И впрыскивается, как это (дает объем в месте инъекции):

@ViewScoped 
class UserView { 

    @Inject @ApplicationScoped 
    UserDetails userDetails; 
    . 
    . 
} 

Это не удалось! .. Инъецированная фасоль не вводила в application scope, но вместо этого получил dependent scope (View Scope в моем случае).

мне пришлось создать Producer & Qualifier где @Produces метод обеспечивает боб в желаемом application scope. Я чувствую, что это расширение продюсера/квалификатора оказывается накладным, если в этом случае мне нужно ввести класс UserDetails в application scope.

Thing is, UserDetails Класс является частью стороннего банкета. Этот класс не имеет объявленной области и является POJO. Я не могу изменить его исходный код.

Исходя из вышеизложенного, у меня есть два вопроса:

  1. Почему кто-то будет создавать классы фасоли, определенные без области, когда они знают, что бобы должны быть введены в рамках определенной области? Будет ли эта практика делать что-то хорошее с точки зрения дизайна?

  2. Поскольку я не контролирую исходный код классов bean и поскольку они не связаны ни с какой областью, является ли расширение продюсера/квалификатора единственным хорошим способом для вставки таких компонентов в нужную область?

ответ

4

1.Объект без видимой области - используется @Dependent

CDI будет обрабатывать область Object без изменений как @Dependent scope.

Экземпляр зависимого компонента никогда не используется между разными клиентами или различными точками впрыска. Это строго зависимый объект другого объекта. Он создается при создании объекта, к которому принадлежит , и уничтожается, когда объект, которому он принадлежит, является уничтожен.

Бобы с областью видимости @ Зависимые не нуждаются в прокси-объекте. Клиент имеет прямую ссылку на свой экземпляр.

Spring IoC DEV: КДИ @Dependent сфера очень похожа на рамки Spring IoC прототипа.

2. Если не использовать @Produces - Just @Inject

CDI создаст новый экземпляр UserDetails для каждой инъекции (@Dependent объема). Здесь нет данных для обмена! Вы не можете определить область действия, как вы это делали (при инъекции).

3. С помощью @Produces затем @Inject

Вы можете контролировать объем UserDetails объекта (ApplicationScoped, SessionScoped или RequestScoped)

public class Producers { 

    @Produces @ApplicationScoped 
    public UserDetails createUserDetails() { 
     // Initialize UserDetails 
    } 

    public void release(@Disposes UserDetails userDetails) { 
     // Release userDetails if you have to 
    } 
} 

4. Еще один способ: Продлить UserDetails, если возможно

@ApplicationScoped // Or @SessionScoped, @RequestScoped 
    public class UserDetailsImpl extends UserDetails { 
     // 
    } 

Если вы хотите ApplicationScoped для UserDetails. Можно использовать путь 3 или путь 4.

+0

На стороне заметьте, не могли бы вы ответить на это: В случае производителя контейнеры CDI уже знают, что введенный объект будет иметь определенный тип области? На заднем плане, как инъекция через производителя отличается от «простой инъекции (случай 1 моего первоначального вопроса)»? – user2918640

+0

Да. CDI знает, какой объем используется для компонента. Область использования - это область, определенная при определении Produces. Вы не можете изменить область действия компонента, указав область действия при вводе. – Loc

2

Объем всегда определяется для компонента, а не для точки впрыска.

Точка впрыска не может изменить объем впрыскиваемого компонента.

0

Я думаю, что вы можете вставить @ApplicationScoped bean как be @Dependent bean, указав @New аннотацию рядом с точкой впрыска, но вы не можете сделать обратное.

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