@Scope(“请求") 不起作用 [英] @Scope("request") not working

查看:23
本文介绍了@Scope(“请求") 不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在试验 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 中看到,服务方法被执行.当我尝试使用上述 beans 属性时,我什么也没看到.但是,我能够访问用于用户会话管理的会话范围 bean.

抱歉,这个问题太幼稚了.非常感谢任何解决问题的意见.

以下是我的代码片段.这就是我调用 bean 的方式:

<p:commandLink id="ajax" actionListener="#{personalBean.getPersonalInfo}" style="margin-left:5px;"><h:outputText value="个人信息"/><br/></p:commandLink></h:form>

下面是请求范围的托管 bean.

package com.test.model;@ManagedBean@Scope("请求")公共类 PersonalBean 实现了 Serializable {私有静态最终长serialVersionUID = 199L;private Personal_Basicpersonal_Basic;私人 IPpersonalService 个人服务;@注入公共 PersonalBean(最终 IPersonalService 个人服务){this.personalService = 个人服务;}公共字符串 getPersonalInfo() {System.out.println("

PersonalBean#getPersonalInfo 调用...**");用户 user = null;Personal_Basicpersonal_Basic =personalService.getPersonalBasic();this.setPersonal_Basic(personal_Basic);System.out.println("personal_Basic 数据:"+personal_Basic);System.out.println("PersonalBean#getPersonalInfo 结束...");返回/page/personal.html";}//类成员的 getter/setter 跟随}

PersonalService 实现使用@Service 进行注释.

以下是spring配置xml的摘录.

<context:annotation-config/><context:component-scan base-package="com.test"/>………………………………</豆类>

以下是faces-config.xml的摘录

<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"版本=2.0"><应用程序><el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver><资源包><base-name>消息</base-name><var>msg</var></resource-bundle><locale-config><default-locale>en</default-locale></locale-config></应用程序>………………………………………………………………………………………………………………………………………………………………</faces-config>

解决方案

元素扫描并注册所有bean默认使用@Component、@Repository、@Service 或@Controller 进行注释.

Spring 还提供对 javax.annotation.ManagedBean(不是 javax.faces.bean.ManagedBean)和 JSR-330 标准注解的支持,并且这些也被 Spring 扫描但是您需要将以下依赖项添加到您的项目中.

<依赖><groupId>javax.inject</groupId><artifactId>javax.inject</artifactId><版本>1</版本></依赖>

您可以看到 Spring 注解的所有等效注解 here,如您所见,@Component 的等价物是 @Named 并且范围使用 Springs @Scope 注释而不是 javax.inject.scope 如前所述.因此,如果您希望 Spring 管理应用程序中的所有 bean,您可以使用 @Component@Namedjavax.annotation.ManagedBean 注释并使用@Autowired 或@Inject 注入它们.

对于您的问题,为什么用 javax.faces.bean.ManagedBean 注释的 bean 似乎已初始化但不起作用是因为如@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公共类 PersonalBean 实现了 Serializable {@ManagedProperty(value="#{personalService}")私人 IPpersonalService 个人服务;公共 IPersonalService getPersonalService() {返回个人服务;}公共无效 setPersonalService(IPersonalService 个人服务){this.personalService=个人服务;}

或者你也可以使用

手动获取Spring bean

org.springframework.web.context.support.WebApplicationContextUtils 像这样:

私有对象 getSpringBean(String name){WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext((ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext());返回 ctx.getBean(name);}

并像这样使用它:

Personal_Basicpersonal_Basic = ((IPersonalService) getSpringBean("personalService")).getPersonalBasic();

但是,不是在您的应用程序中使用两个容器,您可以通过使用 @Component 注释 JSF bean 来使用 Spring 容器来管理所有 bean,并且没有任何我知道的含义并且应该完全可以使用Spring注解.

另见:

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

<h:inputText  id="lastName" value="#{personalBean.personal_Basic.firstName}"  label="Last Name"  required="true" />

The request starts from a command link's invocation to bean method, service and returns the page. I could see in servers console Bean, service methods are executed. I am not seeing anything when I try to use beans attributes as above. However I am able to access session scoped bean used for session management of the user.

Sorry if this question is too naive. Any input to resolve the problem is greatly appreciated.

Below are my code snips. This is how I call the bean:

<h:form>
    <p:commandLink id="ajax" actionListener="#{personalBean.getPersonalInfo}" style="margin-left:5px;">  
        <h:outputText value="Personal Info" />  <br/>
    </p:commandLink>  
</h:form>

Below is the request scoped managed 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("

PersonalBean#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 implementation is annotated with @Service.

Below is the excerpt from spring configuration 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>

Below is the excerpt from 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>

解决方案

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:

这篇关于@Scope(“请求") 不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆