I am experimenting with JSF and Primefaces ( JSF 2.0.2 ,PrimeFaces 3.0.5, Spring 3.0.0). It seems I am unable to access managed bean from a xhtml page such as
The <context:component-scan base-package="com.test"/>
element scans and registers all beans annotated with @Component, @Repository, @Service, or @Controller by default.
Spring also offers support for javax.annotation.ManagedBean
(not javax.faces.bean.ManagedBean
) and JSR-330 standard annotations and these are also scanned by Spring but you need to have the following dependency added to your project.
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
You can see all the equivalent annotations for Spring annotations here, as you can see the equivalent of @Component is @Named and for the scope use Springs @Scope annotation instead of javax.inject.scope
as mentioned.
So if you want Spring to manage all the beans in your application you can use either @Component
, @Named
and javax.annotation.ManagedBean
annotation and inject them using @Autowired or @Inject.
And to your question why beans annotated with javax.faces.bean.ManagedBean
seem to be initialized but do not work is because as mentioned by @BalusC, @Inject is not supported in JSF you have to use @ManagedProperty annotation.
A little background on how it all works with Spring and JSF:
Actually there are two IOC containers in your application now with JSF and Spring, when the application starts up. First the org.springframework.web.jsf.el.SpringBeanFacesELResolver configured in your faces-config.xml delegates to the Spring root WebApplicationContext first resolving name references to Spring-defined beans, then to the default resolver of the underlying JSF implementation.
Now when the JSF bean is first looked up it is constructed and then the managed property is set via the setter method so you can inject a Spring bean using the @ManagedProperty annotation like this:
package com.test.model;
@ManagedBean
@RequestScoped
public class PersonalBean implements Serializable {
@ManagedProperty(value="#{personalService}")
private IPersonalService personalService;
public IPersonalService getPersonalService() {
return personalService;
}
public void setPersonalService(IPersonalService personalService) {
this.personalService= personalService;
}
or you can also manually get the Spring bean using
org.springframework.web.context.support.WebApplicationContextUtils
like this:
private Object getSpringBean(String name){
WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(
(ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext());
return ctx.getBean(name);
}
and use it like this:
Personal_Basic personal_Basic = ((IPersonalService) getSpringBean("personalService")).getPersonalBasic();
But instead of using two containers in your applications you can just use the Spring container to manage all your beans by annotating JSF beans with @Component and there are no implications as such that I am aware of and should be perfectly alright to use Spring annotations.
See also:
You cannot mix @ManagedBean with spring scopes, You have to choose between @ManagedBean and @RequestScope or @Componenet and @Scope("session")