guys i'm using jsf 2.0 with spring.
I have annotated a method in a managed bean with #PostConstruc, but if in the bean there aren't field connected to the jsf page the #PostConstruct method isn't called even if in the jsf page there is an action method connected to the Bean.
Thank you in advance.
Added code for explaination:
this si my BackingManagedBean
#ManagedBean(name="utenteBean")
#ViewScoped
public class UtenteBean extends SupportBean implements Serializable
While this is my ControllerManagedBean
#ManagedBean(name="gestisciUtentiController")
#ViewScoped
public class GestisciUtentiController extends MessageSupportBean implements Serializable {
#ManagedProperty(value="#{utenteBean}")
private UtenteBean utenteBean;
public void setUtenteBean(UtenteBean utenteBean) {
this.utenteBean = utenteBean;
}
#PostConstruct
public void loadBean()
{
try
{
utenteBean.setUtentis(getFacadeFactory().getUtenteFacade().readAllOrdered(Utente.class, "username"));
}
catch (ApplicationException e)
{
setExceptionMessage(e.getLocalizedMessage(), e.getLocalizedMessageDetail());
}
}
http://blog.icefaces.org/blojsom/blog/default/2009/04/23/Making-distinctions-between-different-kinds-of-JSF-managed-beans/ i'm trying to use this approch. You think that that approch isn't correct? –
I'm not sure. That article mentions that the model is typically to be placed in the session scope. This is actually a poor approach. Injecting a session scoped bean in a request scoped bean makes sense if the session scoped one is for example the logged-in user and the request scoped one is bound to the form.
In your case you should just make the model bean a property of the controller bean and use #{gestisciUtentiController.utenteBean.someProperty} instead of #{utenteBean.someProperty}.
I've some "JSF design" questions before, you may find them useful as well:
JSF MVC design question
JSF / Java Design Question
What components are MVC in JSF MVC framework?
Related
Question 1) From my understanding spring creates singletons objects, So when I have a controller like below with a autowired service, will that affect threadsafety.
Question 2) If I declare a int type variable at class level and use it in controller or service, will it affect thread safety?
#Controller
public class LoginController {
#Autowired
public DaoService daoservice;
#RequestMapping("/")
public String getBookInfo() {
Book book = daoservice.getBookbyId(1L);
System.out.println(book.getTitle());
return "welcome";
}
}
#Service
public class DaoService {
#Autowired
public BookRepository BookRepo;
public Book getBookbyId(Long Id) {
Book book = BookRepo.findOne(Id);
return book;
}
}
Q.1 : Are Spring Beans Thread Safe?
Answer: No.
Spring don't give you thread safety for their bean. Spring provide different type of bean scope like (Prototype,Singleton etc). If Prototype then a new bean create each time it invoke where a singleton bean created for one time and shared in application context.
If you are thinking for HTTP request, then 2 or more request can come.Hence new instance of a bean is created in each request scope. So you can think they are thread safe in context of HTTP request but it's not truly thread safe by spring itself.Because several thread can share the bean within the same HTTP request context.
Q.2 : Are Class variable Thread Safe?
Answer: No
Quoted from here
All private member variables are shared. They might be final, but that only means that the references can't be changed. Any mutable state must be synchronized.
I am using Vaadin Spring 1.0.0 and trying to figure out how could I inject beans that are available only within UI scope (when the user has the page opened) into classic spring #Component beans. Simple, let's have classes:
#Component
public class A {
#Inject
private IB b;
}
#UIScope
#SpringComponent
public class B implements IB {
}
And obviously during startup:
Caused by: java.lang.IllegalStateException: No VaadinSession bound to current thread
What is the normal way how to do it? I understand the whole concept, that beans are initialized on startup when UI scope is not available, but I use common libraries which are implemented in Spring with #Component and I want to implement some of the interfaces, but I can do it only in UI scope and not during startup.
Try injecting an aop scoped proxy instead.
For example:
#Scope(value="vaadin-ui", proxyMode=ScopedProxyMode.INTERFACES)
#SpringComponent
public class B implements IB {
}
I think that should work.
You need to get it from ApplicationContext itself:
#Component
public class A {
#Autowired
private ApplicationContext context;
public B getCurrentB(){
return context.getBean(B.class);
}
}
Note that it will throw exception if there is no UI bound to the current thread (normally). In other words, you MUST make sure this method only gets called during a UI request. Any kind of listener in Vaadin should be OK, as long as you're in the same thread with the request.
In SessionListener I want to set some values of #ManagedBean with Session scope that I want to show in JSF.
You'd need to create the managed bean instance yourself.
Bean bean = new Bean();
bean.setSomething(something);
event.getSession().setAttribute("bean", bean); // "bean" is managed bean name.
JSF will just reuse it if it already exist in the session scope (you see, the JSF "session scope" is under the covers represented by attributes of HttpSession). Note that this way any #PostConstruct won't be invoked and any dependencies which needs to be injected by #ManagedProperty, #EJB, etc, won't be injected at all. You'd need to do it yourself as well.
Designtechnically, much better is to perform the job just in the constructor or #PostConstruct method of the backing bean class itself.
#ManagedBean
#SessionScoped
public class Bean {
#PostConstruct
public void init() {
// Here.
}
}
As far as I know that JSF keeps all the session scoped bean in some kind of Map (correct me if I am wrong.).
In my application I have session scoped (managed by Spring and injected into the backing bean) bean named "userDetailsBean".
Is it possible to get all the instances of the bean created for different user in some sort of collection by the help of JSF API?
Add and remove them to/from some applicationwide collection/mapping yourself during #PostConstruct and #PreDestroy.
#PostConstruct
public void init() {
allSessionScopedBeans.add(this);
}
#PreDestroy
public void destroy() {
allSessionScopedBeans.remove(this);
}
I have a JSF 2.0 bean:
#ManagedBean
#SessionScoped
public class LoginBean implements Serializable
{
protected String name;
public String getName()
{
return name;
}
//....
}
I have a Spring 3.0 bean:
#Repository
public class Logins
{
#ManagedProperty(value="#{loginBean}")
protected LoginBean loginBean;
public void recordLogin()
{
//... record in db that loginBean.getName() just logged in
}
}
This code doesn't work, Logins.loginBean is never set.
Alternatively (its the same question, simplified) - would the following code ever work?
#Repository
public class SpringBean
{
#ManagedProperty(value="#{session.id}")
protected String id;
//....
}
The ContextLoaderListener and RequestLoaderListener are declared in web.xml.
Is it possible at all to inject a JSF bean into a Spring bean? (Without using yet another extra framework)
Or should I rather convert my JSF bean into a Spring bean and use the DelegatingVariableResolver trick in faces-config.xml? I have already tested this with a test Spring bean, and it works.
Using JSF annotations in spring-managed beans doesn't work. And it shouldn't - you should not inject things from the web layer in the other layers. It should be the other way around - inject spring services (or repositories) into web components (jsf managed beans), and invoke methods on them, passing the managed bean properties as arguments