Probably my question is a trivial one, but I never used an application scope bean before. I need the application bean because I have to do time consuming transactions on the database. my search didn't satisfy my curiosity at all. I don't know why but I didn't manage to initialize the bean (it is null) or it the app crashed. So I have an application scope bean
@ManagedBean(eager=true)
@ApplicationScoped
public class ApplicationContainer {
...
}
eager=true I read that tells JSF to initiate the bean every time when the application server (I use GlassFish) is started.
I read in several places that I just have to put this annotation and the bean gets initialized. For me it doesn't... After I read that if I want to inject the application bean into another bean I have to use @PostConstuct annotation
@ManagedBean
@SessionScoped
public class TestsBean implements Serializable {
private static final long serialVersionUID = 1L;
@ManagedProperty(value = "#{container}")
private ApplicationContainer container;
@PostConstruct
public void init() {
container.contructContainer();
}
this gives an error in other bean that I inject the TestsBean into...
Please tell me the proper way to handle application beans. I an really confused...
Thank you all for your time!
There are 2 potential mistakes.
First, the @ManagedBean(eager=true)
works, as its javadoc says, only on application scoped JSF managed beans. So it works only when you have used @ApplicationScoped
of javax.faces.bean
package (and thus not javax.enterprise.context
package!). The eager=true
basically means that the bean will be auto-instantiated on webapp's startup instead of only later when it's referenced for the first time in EL.
Second, the managed bean name defaults to the classname in decapitalized form according the Javabeans specification. You didn't explicitly specify any managed bean name like @ManagedBean(name="container", eager=true)
, so the managed bean name will default to applicationContainer
, however yet you're still attempting to reference it as #{container}
instead of #{applicationContainer}
.
You are not clear at all on which problems/errors you're facing. If you're getting an exception, you should absolutely read/interpret it and if you're unable to understand it, copypaste it in its entirety -including the stacktrace- in the question. It represents namely the whole answer to your problem at its own. You just have to interpret and understand it (or we just have to explain it in layman's terms). You should really not ignore them and leave them out the question as if they are irrelevant decoration. They are not!
All with all, the complete and proper approach would be, complete with the import declarations just to be sure, and also some poor man's stdout prints for debugging:
package com.example;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
@ManagedBean(eager=true)
@ApplicationScoped
public class ApplicationContainer {
public ApplicationContainer() {
System.out.println("ApplicationContainer constructed");
}
}
package com.example;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class TestsBean implements Serializable {
@ManagedProperty("#{applicationContainer}")
private ApplicationContainer container;
public TestsBean() {
System.out.println("TestsBean constructed");
}
@PostConstruct
public void init() {
System.out.println("ApplicationContainer injected: " + container);
}
public void setContainer(ApplicationContainer container) {
this.container = container;
}
}