我正在试验JSF和Primefaces(JSF 2.0.2,PrimeFaces 3.0.5,Spring 3.0.0)。看来我无法从xhtml页面访问托管bean,例如
<h:inputText id="lastName" value="#{personalBean.personal_Basic.firstName}" label="Last Name" required="true" />
该请求从命令链接对bean方法,服务的调用开始,并返回页面。我可以在服务器控制台Bean中看到服务方法已执行。当我尝试使用上述bean属性时,我什么也没看到。但是,我能够访问用于用户会话管理的会话作用域bean。
抱歉,这个问题太幼稚了。任何解决问题的投入,我们将不胜感激。
以下是我的代码片段。这就是我所说的bean:
<h:form> <p:commandLink id="ajax" actionListener="#{personalBean.getPersonalInfo}" style="margin-left:5px;"> <h:outputText value="Personal Info" /> <br/> </p:commandLink> </h:form>
以下是请求范围的托管Bean。
package com.test.model; @ManagedBean @Scope("request") public class PersonalBean implements Serializable { private static final long serialVersionUID = 199L; private Personal_Basic personal_Basic; private IPersonalService personalService; @Inject public PersonalBean(final IPersonalService personalService) { this.personalService = personalService; } public String getPersonalInfo() { System.out.println("\n\nPersonalBean#getPersonalInfo called...**"); User user = null; Personal_Basic personal_Basic = personalService.getPersonalBasic(); this.setPersonal_Basic(personal_Basic); System.out.println("personal_Basic data:"+personal_Basic); System.out.println("PersonalBean#getPersonalInfo ended..."); return "/page/personal.html"; } // Getters/setters for class members followed }
PersonalService实现使用@Service注释。
以下是spring配置xml的摘录。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <context:annotation-config/> <context:component-scan base-package="com.test"/> ................... ................... </beans>
以下是来自faces-config.xml的摘录
<?xml version="1.0"?> <faces-config xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_2_0.xsd" version="2.0"> <application> <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver> <resource-bundle> <base-name>Messages</base-name> <var>msg</var> </resource-bundle> <locale-config> <default-locale>en</default-locale> </locale-config> </application> ........................... </faces-config>
该<context:component-scan base-package="com.test"/>元件的扫描和注册所有豆类默认使用@Component,@Repository,@Service或@Controller的。
<context:component-scan base-package="com.test"/>
Spring还提供了对javax.annotation.ManagedBean(not javax.faces.bean.ManagedBean)和JSR-330标准注释的支持,Spring也对其进行了扫描,但是你需要在项目中添加以下依赖项。
javax.annotation.ManagedBean
javax.faces.bean.ManagedBean
<dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>
你可以在此处看到Spring注释的所有等效注释,因为你可以看到@Component的等效名称为@Named,并且对于范围,请使用Springs @Scope注释而不是javax.inject.scope如上所述。所以,如果你想Spring来管理所有应用程序中的豆你可以使用@Component,@Named并且javax.annotation.ManagedBean使用@Autowired或@Inject注解并注入他们。
@Component
@Named
对于你的问题,为何使用Bean javax.faces.bean.ManagedBean似乎已初始化但不起作用,是因为如@BalusC所述,JSF不支持@Inject,因此你必须使用@ManagedProperty注释。
关于Spring和JSF的全部工作原理的一些背景知识:
实际上,当应用程序启动时,你的应用程序中现在有了两个带有JSF和Spring的IOC容器。首先,在faces-config.xml中配置的org.springframework.web.jsf.el.SpringBeanFacesELResolver委托给Spring根WebApplicationContext,首先将名称引用解析为Spring定义的bean,然后解析为底层JSF实现的默认解析器。
现在,当首先查找JSF bean时,将对其进行构造,然后通过setter方法设置托管属性,以便你可以使用@ManagedProperty注释注入Spring bean,如下所示:
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; }
或者你也可以使用以下方式手动获取Spring bean
org.springframework.web.context.support.WebApplicationContextUtils 像这样:
org.springframework.web.context.support.WebApplicationContextUtils
private Object getSpringBean(String name){ WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext( (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext()); return ctx.getBean(name); }
并像这样使用它:
Personal_Basic personal_Basic = ((IPersonalService) getSpringBean("personalService")).getPersonalBasic();
但是,除了在你的应用程序中使用两个容器之外,你还可以使用Spring容器通过使用@Component注释JSF Bean来管理所有Bean,并且我没有意识到任何暗示,并且使用Spring注释应该是完全可以的。