JSF 2 使用 @ManagedProperty 注入 Spring bean/service 而没有 xml

Posted

技术标签:

【中文标题】JSF 2 使用 @ManagedProperty 注入 Spring bean/service 而没有 xml【英文标题】:JSF 2 inject Spring bean/service with @ManagedProperty and no xml 【发布时间】:2012-02-14 01:26:15 【问题描述】:

我想使用 jsf 注释和一些 spring 将 spring bean/服务注入 jsf 托管 bean 的注释。 (在 jsf bean 上我只想使用 jsf 注释) 我不想使用 @named / @inject 之类的注释。

我试图在网上找到解决方案,但没有任何运气。

例子

@ManagedBean
@ViewScoped 
public class MyBean 

    @ManagedProperty(value = "#mySpringBean")
    private MySpringBean mySpringBean;

    public void setMySpringBean(MySpringBean mySpringBean) 
        this.mySpringBean = mySpringBean;
    

    public void doSomething() 
    //do something with mySpringBean
    

在不使用 xml 的情况下,这样的事情是否可行。例如, 我不想使用类似的东西

FacesContextUtils.getWebApplicationContext(context).getBean("MySpringBean");

faces-config.xml

<managed-bean>
    <managed-bean-name>myBean</managed-bean-name>
    <managed-bean-class>com.mytest.MyBean</managed-bean-class>
    <managed-bean-scope>view</managed-bean-scope>
    <managed-property>
        <property-name>mySpringBean</property-name>
        <value>#mySpringBean</value>
    </managed-property>
</managed-bean>

上面的内容是否可能有注释和没有注释 定义所有 jsf beans/properties 和 spring beans/properties 配置 xml 文件中的每个 bean?

【问题讨论】:

有趣的是,我使用这种注入方法并且它适用于我,但是我也将属性注入包含在我的applicationContext.xml 中。 Spring EL 解析器似乎不适用于我注意到的 ViewScoped bean。尝试将其更改为 SessionScoped 并查看属性是否被注入。 我想避免applicationContext.xml(我有点固执!谢谢)但是谢谢:) 【参考方案1】:

如果你已经有了 Spring 容器,为什么不使用它的 @Autowired 注解。为此,请按照 Boni 的建议更新您的 faces-config.xml。然后在此之后将这些侦听器添加到您的 web.xml 中

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<listener>
  <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

然后将这些添加到您的 applicationContext.xml

<context:component-scan base-package="com.examples" />

现在您可以使用 Spring 注释,您的 bean 将是这样的:

package com.examples;
@Component
@Scope(value="request")
public class MyBean 
    @Autowired
    private MySpringBeanClass mySpringBean;

使用 @Service 注释您的 MySpringBeanClass

另见:

@Scope("request") not working

【讨论】:

如果你想在 Spring 中使用 ViewScope,你需要编写一个自定义的 ViewScope 类来实现 Scope。关注此博客条目以获取 link【参考方案2】:

将此代码放入您的 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"
    version="2.0">
    <application>
        <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
    </application>
</faces-config>

然后在你的 ManageBean Constructor 调用中;

WebApplicationContext ctx =  FacesContextUtils.getWebApplicationContext(FacesContext.getCurrentInstance());
mySpringBean = ctx.getBean(MySpringBean.class);

MySpringBean 表示你的 Spring Bean 类

【讨论】:

可以在 spring bean 中使用注释而不在 applicationContext.xml 中插入它来完成吗? 谢谢 我让它与 WebApplicationContext ctx 解决方案一起使用。我只是想知道我是否可以跳过它并直接使用 @ManagedProperty(value = "#mySpringBean") :)【参考方案3】:

假设您在 web.xml 和 applicationContext.xml 中正确配置了 Spring。 在 faces-config.xml 中创建以下条目

<application>
     <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>

上面给出的示例代码看起来不错。上面的条目会发生什么是托管属性将首先在 JSF 管理的 bean 中查找,如果未找到将在 Spring 管理的 bean 中搜索。您的 spring bean 应该有适当的注释标记,@ManagedProperty 中给出的名称应该与给 bean 的默认/名称匹配。

正如@Boni 所提到的,它不是必需的,它是自动注入的。我已经按照你的意愿使用了设置。

附注:由于您选择查看范围,请查看此链接The benefits and pitfalls of @ViewScoped

【讨论】:

以上是关于JSF 2 使用 @ManagedProperty 注入 Spring bean/service 而没有 xml的主要内容,如果未能解决你的问题,请参考以下文章

无法将 JSF ViewScoped bean 作为 ManagedProperty 注入 Validator

可以将@ManagedBean 作为@ManagedProperty 注入@WebServlet?

注入 vs ManagedProperty [重复]

在JSF托管bean的构造函数中访问会话bean数据

JSF管理多元化的财产

JSF Managed Beans 不使用 spring 安全过滤器