JSF注入托管属性,好模式?

Qua*_*lay 2 jsf design-patterns code-injection postconstruct managed-bean

我对JSF很新,并没有真正"习惯"不同的思维,所以我在努力(我假设)是基本的.

假设我有一个类User,它是一个会话bean.

假设我有10000个对象的控制器,比如Factory,它需要能够将它们中的一些设置为"锁定",在我们的例子中,它意味着"锁定"字段不再变为空,而是引用"LockedItem"宾语.

这是我无法工作的地方:LockedItem,当你实现它时,应该引用当前登录的用户.我该怎么做?

我尝试使用@managedproperty进行注入,但是在LockedItem.constructor中它是null(这是正常的我假设)然后我尝试了@PostConstruct方法,但是这个方法永远不会被调用(为什么?即使我把它变成了一个托管bean ...是只有在".xhtml"创建对象时调用的postconstruct方法?)或者我应该使用"java se"技巧,比如使用户静态?


代码澄清为什么没有调用@PostConstruct("Seat"之一):

.xhtml

<h:outputLabel id="user" value="Hello #{user.name}" />
<h:outputLabel id="car" value="you have #{car.brand}" />
Run Code Online (Sandbox Code Playgroud)

用户

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;
    }


}
Run Code Online (Sandbox Code Playgroud)

汽车

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;
    }


}
Run Code Online (Sandbox Code Playgroud)

座位

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

谢谢 !

Bal*_*usC 5

@PostConstruct是正确的方式.

如果您使用newoperator(显然)自己实例化bean,则不会调用它.只有当JSF首次在EL上下文中引用时,JSF才会实例化并管理bean本身#{bean}.这确实通常发生在视图方面,但这也可能发生在模型/控制器方面@ManagedProperty("#{bean}")Application#evaluateExpressionGet().

你绝对不应该做User静态.它将在应用程序范围内共享,而不是在整个会话范

另一种方法是只通过当前User作为构造函数的参数LockedItem,或者调用初始化方法自己,肯定如果类没有在所有代表一个合法的JSF支持bean.