Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

jsf - Cant access property of managed bean from another managed bean

I want to access the property of a @SessionScoped bean in another bean using @ManagedProperty. In short, I want to access the name property of firstBean in secondBean.

@ManagedBean
@SessionScoped
public class FirstBean implements Serializable{
    private String name;
    //...other attributes
    //...constructor
    public String getSelectedModel() {
        return selectedModel;
    }

    public void setSelectedModel(String selectedModel) {
        this.selectedModel = selectedModel;
    }
    //other getters&setters
}

And second bean:

@ManagedBean
@SessionScoped
public class SecondBean implements Serializable{

@ManagedProperty(value="#{firstBean}")
private FirstBean firstBean

public SecondBean() {
    System.out.println(firstBean.getName());
}
public IndexBean getFirstBean() {
    return firstBean;
}

public void setFirstBean(FirstBean firstBean) {
    this.firstBean = firstBean;
}

When I run this, I always get NullPointerException on System.out.println(firstBean.getName()); in the constructor of second bean, which seems to mean that I need to create a new instance of firstBean.

But strangely, when I commented out this line, I can do something like this with no errors, which means that firstBean is actually a property of secondBean.

<h:outputText value="#{secondBean.firstBean.name}" />

What's the problem here?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

It's not possible to access an injected dependency in the constructor. You're basically expecting that Java is able to do something like this:

SecondBean secondBean; // Declare.
secondBean.firstBean = new FirstBean(); // Inject.
secondBean = new SecondBean(); // Construct.

It's absolutely not possible to set an instance variable if the instance is not constructed yet. Instead, it works as follows:

SecondBean secondBean; // Declare.
secondBean = new SecondBean(); // Construct.
secondBean.firstBean = new FirstBean(); // Inject.

Then, in order to perform business actions based on injected dependencies, use a method annotated with @PostConstruct. It will be invoked by the dependency injection manager directly after construction and dependency injection.

So, just replace

public SecondBean() {
    System.out.println(firstBean.getName());
}

by

@PostConstruct
public void init() { // Note: method name is fully to your choice.
    System.out.println(firstBean.getName());
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...