Вопрос по design-patterns, jsf, managed-bean, postconstruct, code-injection – Инъекция JSF с управляемым свойством, хороший шаблон?

2

Я совсем новичок в JSF и на самом деле не "использовал" к другому мышлению, поэтому я борюсь за то, что (я полагаю) является основным.

Допустим, у меня есть класс User, который является сессионным компонентом.

Допустим, у меня есть контроллер из 10000 объектов, скажем, Factory, который должен быть в состоянии установить некоторые из них как «заблокированные», в нашем случае это означает, что «заблокирован» поле больше не становится нулевым, но ссылается на «LockedItem» объект.

Вот где я не могу заставить вещи работать: LockedItem, когда вы его создаете, должен ссылаться на пользователя, который в данный момент вошел в систему. Как я должен это делать?

Я попытался выполнить инъекцию с @managedproperty, но в LockedItem.constructor это значение равно нулю (что, как я полагаю, нормально), затем я попытался использовать метод @PostConstruct, но этот метод никогда не вызывается (почему? Даже если я сделаю его управляемым ... методы постконструкции вызываются только тогда, когда объект создается с помощью & quot; .xhtml & quot;?) Или я должен использовать & quot; java se & quot; трюк, как сделать пользователя статичным?

Код, поясняющий, почему не вызывается @PostConstruct (один из "Seat"):

.xhtml

<h:outputLabel id="user" value="Hello #{user.name}" />
<h:outputLabel id="car" value="you have #{car.brand}" />

User

package test;

import java.io.Serializable;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class User implements Serializable {
    private String name ;

    public User()
    {
        name = "toto"; 
        System.out.println("User constructor");
    }

    public String getName() {
        return name;
    }

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


}

Car

package test;

import java.io.Serializable;

import javax.faces.bean.ManagedBean;

@ManagedBean
public class Car implements Serializable {
    private String brand ;
    private Seat seat ;

    public Car()
    {
        brand = "audi" ;
        seat = new Seat();
        System.out.println("Car constructor") ;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }


}

Seat

package test;

import java.io.Serializable;

import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;

@ManagedBean
public class Seat implements Serializable {
    private int nb ;
    private String userName ;

    @ManagedProperty("#{user}")
    private User user ;

    public Seat()
    {
        nb = 4 ;
        userName="na";
        System.out.println("! Seat constructor ") ;
    }

    @PostConstruct
    public void init()
    {
        System.out.println("!! Seat postconstruct : "+user.getName());
    }

    public User getUser() {
        return user;
    }

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

    public int getNb() {
        return nb;
    }

    public void setNb(int nb) {
        this.nb = nb;
    }
}

Спасибо !

Ваш Ответ

1   ответ
5

@PostConstruct это правильный путь.

Он не вызывается, если вы сами создаете экземпляр компонента, используяnew оператор (очевидно). Он вызывается только в том случае, если JSF создает экземпляр и управляет самим компонентом всякий раз, когда на него впервые ссылаются в контексте EL, например,#{bean}, Это действительно обычно происходит на стороне вида, но это также может происходить на стороне модели / контроллера@ManagedProperty("#{bean}") или жеApplication#evaluateExpressionGet().

Вы не должны абсолютноUser статичный. Это будет общедоступным приложением, а не сессией.

Альтернативой является просто передать текущийUser в качестве аргумента конструктораLockedItemили для вызова метода инициализацииyourselfнаверняка, если этот класс вообще не представляет легитимный компонент поддержки JSF.

Добро пожаловать.
Вы должны иметь@ManagedProperty("#{seat}") вместоnew Seat().
Большое спасибо ! Qualaelay
Спасибо BalusC! Я попробовал все это в небольшом тестовом примере, и до сих пор не могу получить PostConstruct класса ("Seat"), вызываемого с использованием @ManagedProperty, если бы вы поняли, что неправильно в мой код (опубликован как ответ)? (Обратите внимание, что он действительно вызывается, если у меня есть & lt; h: outputLabel id = & quot; seat & quot; value = & quot; у вас есть # {seat.nb} & quot; seat / & gt;) Qualaelay
В соответствии с вашими решениями у меня все еще есть «шаблон» вопрос на самом деле из-за абстрактного В моем конкретном случае у меня естьLibraryObject который является абстрактным и определяет реализацию по умолчанию для блокировки объекта (то естьLockedItem). LockedItem должен знать, ктоUser (сессионный компонент), чтобы получить его имя. Изначально ниLibraryObject ниLockedItem бобы Лучший способ сделать это, кажется, сделатьLibraryObject управляемый компонент, на который я добавляюUser и, как вы сказали, создать новыйLockedItem даваяUser ссылка, но я не могу, так как она абстрактна ... Есть идеи? Qualaelay

Похожие вопросы