JSF注入管理财产,格局好吗? [英] JSF injection with managed property, good pattern?

查看:138
本文介绍了JSF注入管理财产,格局好吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对JSF来说非常新鲜,并没有真正使用不同的思维,所以我正在努力(我假设)是基本的。



说我有一个类User,它是一个会话bean。假设我有一个10000个对象的控制器,说Factory,需要将其中的一些设置为锁定,在我们的情况下,这意味着锁定字段不再变为null,但引用了一个LockedItem对象。



这是我无法使事情发生的地方:LockedItem,当你实验时,应该引用当前登录的用户,我该怎么做?



我尝试使用@managedproperty进行注入,但在LockedItem.constructor中为空是正常的,我假设)然后我尝试一个@PostConstruct方法,但是这个方法是永远不会调用的(为什么?即使我使它成为一个managedbean ...只有当该对象是由.xhtml创建的时候才调用的postconstruct方法?)
或者我应该使用java se技巧,就像使用户静态吗?






代码澄清为什么一个@PostConstruct不被调用(Seat)之一:



.xhtml

 < h:outputLabel id =uservalue =Hello#{user.name}/> 
< h:outputLabel id =carvalue =你有#{car.brand}/>

用户

 包测试; 

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


}

汽车

 包测试; 

import java.io.Serializable;

import javax.faces.bean.ManagedBean;

@ManagedBean
public class Car implements Serializable {
private String brand;
私人座椅;

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

public String getBrand(){
返回品牌;
}

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


}

座位



 包测试; 

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用户;

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上下文中首次引用时,JSF实例化和管理bean本身才被称为,所以#{bean} 。这通常发生在视图侧,但这也可能发生在模型/控制器端,由 @ManagedProperty(#{bean}) 应用程序#evaluateExpressionGet()



您绝对不应该使用户 static。它将被全局共享,而不是全局共享。



另一种方法是将当前 User 作为构造函数参数传递给 c $ c>或者为了调用自己的初始化方法 ,确定该类根本不代表合法的JSF支持bean。


I'm quite new to JSF and not really "used" to the different thinking so I'm struggling on what (I assume) is basic.

Lets say I have a class User, which is a session bean.

Lets say I have a controller of 10000 objects, say Factory, that needs to be able to set some of them as "locked", in our case it means that the "locked" field does not become null anymore but reference a "LockedItem" object.

This is where I can't get things working : LockedItem, when you instanciate it, is supposed to reference the user currently logged in. How am I supposed to do that ?

I tried injection with @managedproperty, but it is null in LockedItem.constructor (which is normal I assume) then I tried in a @PostConstruct method, but that method is never called (why ? Even if I make it a managedbean... are the postconstruct methods only called when the object is created by the ".xhtml" ?) Or should I use a "java se" trick, like making the User static ?


Code to clarify why is a @PostConstruct not called (the one of "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;
    }
}

Thanks !

解决方案

The @PostConstruct is the right way.

It's not called if you instantiate the bean yourself using new operator (obviously). It's only called if JSF instantiates and manages the bean itself whenever it's referenced for the first time in EL context like so #{bean}. This indeed usually happens in the view side, but this can also happen in model/controller side by @ManagedProperty("#{bean}") or Application#evaluateExpressionGet().

You should absolutely not make the User static. It would be shared applicationwide, not sessionwide.

An alternative is to just pass the current User as constructor argument of LockedItem, or to invoke the initialization method yourself, for sure if that class does not represent a legit JSF backing bean at all.

这篇关于JSF注入管理财产,格局好吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆