Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JSF注入与托管属性,良好的模式?_Jsf_Design Patterns_Code Injection_Managed Bean_Postconstruct - Fatal编程技术网

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

JSF注入与托管属性,良好的模式?,jsf,design-patterns,code-injection,managed-bean,postconstruct,Jsf,Design Patterns,Code Injection,Managed Bean,Postconstruct,我对JSF非常陌生,并不真正“习惯”不同的思维方式,所以我在(我假设)什么是基本的问题上苦苦挣扎 假设我有一个类User,它是一个会话bean 假设我有一个10000个对象的控制器,比如说工厂,它需要能够将其中一些对象设置为“锁定”,在我们的例子中,这意味着“锁定”字段不再为空,而是引用一个“LockedItem”对象 这就是我无法让事情正常工作的地方:当你实例化它时,它应该引用当前登录的用户。我该怎么做 我尝试使用@managedproperty进行注入,但它在LockedItem.const

我对JSF非常陌生,并不真正“习惯”不同的思维方式,所以我在(我假设)什么是基本的问题上苦苦挣扎

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

假设我有一个10000个对象的控制器,比如说工厂,它需要能够将其中一些对象设置为“锁定”,在我们的例子中,这意味着“锁定”字段不再为空,而是引用一个“LockedItem”对象

这就是我无法让事情正常工作的地方:当你实例化它时,它应该引用当前登录的用户。我该怎么做

我尝试使用@managedproperty进行注入,但它在LockedItem.constructor中为null(我认为这是正常的),然后我尝试使用@PostConstruct方法,但从未调用过该方法(为什么?即使我将其设为managedbean…是否只有在由“.xhtml”创建对象时才调用PostConstruct方法?) 或者我应该使用“JavaSE”技巧,比如让用户保持静态


用于澄清为何未调用@PostConstruct的代码(“Seat”之一):

.xhtml

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

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


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


}
座位

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

谢谢

PostConstruct是正确的方法

如果您自己使用
new
操作符实例化bean,则不会调用它(显然)。只有当JSF在EL上下文中第一次引用bean时(如so
#{bean}
),它才会被调用。这确实通常发生在视图端,但这也可能发生在模型/控制器端的
@ManagedProperty(“#{bean}”)

您绝对不应该将
用户设置为静态。它将在应用程序范围内共享,而不是在会话范围内共享


另一种方法是将当前的
用户
作为
LockedItem
的构造函数参数传递,或者自己调用初始化方法,如果该类根本不代表合法的JSF支持bean的话。

谢谢BalusC!我在一个小测试用例中尝试了所有这些,但似乎仍然无法使用@ManagedProperty获得一个类(“Seat”)的后构造,您是否知道我的代码(发布为reply)中有什么错误?(请注意,如果我有,它确实会被调用)您应该有一个
@ManagedProperty(“#{seat}”)
而不是
new seat()
。根据您的解决方案,实际上由于抽象,我仍然有一个“模式”问题。在我的具体例子中,我有一个
LibraryObject
,它是抽象的,并定义了锁定对象的默认实现(即关联
LockedItem
LockedItem
必须知道谁是
用户(会话bean)才能获取其名称。最初,nor
LibraryObject
LockedItem
都是bean。最好的方法似乎是将
LibraryObject
作为一个managedBean,我在其上注入
User
,并且,正如您所说,创建一个新的
LockedItem
,给
User
引用,但我不能,因为它的抽象性。。。有什么想法吗?