2013-12-13 4 views
0

Я хочу использовать один и тот же объект «Пользователь» в объектах Farma и Pata. Пользователь объекта сначала инициализируется внутри объекта Farma. Я попытался аннотироваться с @inject, но пользователь объекта внутри Pata имеет имя с нулевым значением. Пожалуйста, может кто-нибудь помочь мне понять, что я делаю неправильно? Спасибо!Как использовать CDI и инъекции зависимостей

@Named 
@SessionScoped 
public class Farma implements Serializable { 
    @Inject private User user; 

    @PostConstruct 
    public void initialize(){ 
     user.setName("MyName"); 
    } 
    // Getters and Setters 
} 

@Named 
@SessionScoped 
public class Pata implements Serializable { 
    @Inject private User user; 

    public String getFuzzyName() { 
     // Here I want to use the object "user" with the name "MyName" to do some logic 
    } 
    // Getters and Setters 
} 

public class User implements Serializable { 
    private String name; 

    // Getters and Setters 
+0

Попробуйте сделать пользователя '@Named @ SessionScoped'. – axiopisty

+0

Я пробовал, но он не работает. И Netbeans показали, что «нет разрешенных для инъекций компонентов». Я использую JDK6 и Glassfish 3. – voidmain

+0

Можете ли вы опубликовать свой проект на github? – axiopisty

ответ

1

Простое определение объекта пользователя не позволит вам его инициализировать. Используйте «метод производителя» для управления созданием bean-компонента. Попробуйте это:

@SessionScoped 
public class Pata implements Serializable { 
    @Inject 
    @SessionUser // inject here using the producer method 
    private User user; 

    public String getFuzzyName() { 
     return user.getName(); 
    } 
} 
@SessionScoped 
public class Farma implements Serializable { 
    @Produces 
    @SessionUser // qualifier to tie injection points to this method 
    @SessionScoped // to ensure it will be called once per session for any number of injection points 
    public User produceUser() { 
     System.out.println("Creating user"); 
     User u = new User(); 
     u.setName("User"); 
     return u; 
    } 
} 
////// that's your custom qualifier, it's in a separate file 
@Qualifier 
@Retention(RetentionPolicy.RUNTIME) 
@Target({METHOD, FIELD, PARAMETER, TYPE}) 
public @interface SessionUser {} 

// no scopes here, it is defined by the producer method 
public class User implements Serializable { 
    private String name; 
    public void setName(String name) { 
     this.name = name; 
    } 
    public String getName() { 
     return name; 
    } 
} 
0

Вам необходимо понять, scoping of CDI фасоль. Область по умолчанию, если она не указана, является областью @Dependent, что означает, что объект существует для обслуживания именно одного клиента (bean) и имеет тот же жизненный цикл, что и этот клиент (bean).

В этом случае это означает, что пользователь в Farma существует только для класса Farma и живет в течение жизни класса Farma.

Пользователь в Pata - это другой экземпляр, а его жизненный цикл соответствует параметру Pata.

Необходимо правильно разместить объект пользователя.

0

Как сказал axiopisty, добавив @Named @SessionScoped правильный путь.

Я пробовал, и он отлично работает.

@Named 
@SessionScoped 
public class Pata implements Serializable { 
    @Inject 
    private User user; 

    public String getFuzzyName() { 
     System.out.println(user.getName()); 
     return user.getName(); 
    } 

    public User getUser() { 
     return user; 
    } 

    public void setUser(final User user) { 
     this.user = user; 
    } 
} 

@Named 
@SessionScoped 
public class Farma implements Serializable { 
    @Inject 
    private User user; 

    @PostConstruct 
    public void initialize() { 
     user.setName("MyName"); 
    } 

    // Getters and Setters 

    public User getUser() { 
     return user; 
    } 

    public void setUser(final User user) { 
     this.user = user; 
    } 
} 


@Named 
@SessionScoped 
public class User implements Serializable { 
    private String name = "Default"; 

    public String getName() { 
     return name; 
    } 

    public void setName(final String name) { 
     this.name = name; 
    } 
} 


<h:outputText value="#{farma}"></h:outputText><br /> 
<h:outputText value="#{pata}"></h:outputText><br /> 
<h:outputText value="#{pata.fuzzyName}"></h:outputText> 
+0

Ну, это может сработать, но это действительно хрупкое. CDI создает бобы как можно лениво. Таким образом, в вашем коде нет гарантии, что 'Frarma.initialize()' вызывается до доступа пользователя. Принимая во внимание, что '@ Produces' гарантирует, что' User' всегда был инициализирован, когда вам это нужно. – Yuri

+0

Как я понимаю, проблема заключалась в том, чтобы использовать один и тот же объект в обоих CDI-бобах, и это автоматически предоставляется контейнером. Инициализация пользователя я ожидал бы whitin метода PostConstruct в User CDI Bean. –

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