Spring JSF集成:如何在JSF托管bean中注入Spring组件/服务?

Ron*_*las 39 integration jsf spring dependency-injection managed-bean

我知道托管bean的工作方式类似于控制器,因为您唯一的任务是将视图层与模型"链接"起来.

要使用bean作为托管bean,我必须声明@ManagedBean注释,这样做我可以直接与bean通信JSF.

如果我想在这个managedBean中注入一些组件(来自Spring),我有两种可能的方法:

  1. 在ManagedBean中选择属性(如"BasicDAO dao")并@ManagedProperty(#{"basicDAO"})在属性上方声明.这样做,我"basicDAO"在ManagedBean中从Spring 注入bean .

  2. 在ManagedBean Class中声明了@Controller,然后我将拥有@ManagedBean@Controller注释一起.在物业中"BasicDAO dao"我必须使用@AutowiredSpring.

我的理解是否正确?

Bal*_*usC 78

@ManagedBean VS @Controller

首先,您应该选择一个框架来管理您的bean.您应该选择JSF或Spring(或CDI)来管理您的bean.虽然以下工作,但从根本上说是错误的:

@ManagedBean // JSF-managed.
@Controller // Spring-managed.
public class BadBean {}
Run Code Online (Sandbox Code Playgroud)

您最终得到了两个完全独立的同一个托管bean类实例,一个由JSF管理,另一个由Spring管理.当你引用它时,不清楚哪一个实际上会用在EL中#{someBean}.如果你已SpringBeanFacesELResolver注册faces-config.xml,那么它将是Spring管理的,而不是JSF管理的.如果你没有,那么它将是由JSF管理的.

此外,当你宣布一个JSF托管bean具体范围,如@RequestScoped,@ViewScoped,@SessionScoped@ApplicationScopedjavax.faces.*包时,它才会被认可和使用@ManagedBean.它不会被理解,@Controller因为它期望它自己的@Scope注释.缺席时,默认为单例(应用程序范围).

@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
@Controller // Spring-managed (without own scope, so actually becomes a singleton).
public class BadBean {}
Run Code Online (Sandbox Code Playgroud)

当您引用上面的bean时#{someBean},它将返回Spring管理的应用程序作用域bean,而不是JSF管理的视图作用域bean.


@ManagedProperty VS @Autowired

特定@ManagedProperty于JSF的工作仅适用于JSF管理的bean,即在您使用时@ManagedBean.特定@Autowired于Spring的工作仅适用于Spring管理的bean,即在您使用时@Controller.以下方法不太相同或不相同,不能混用:

@ManagedBean // JSF-managed.
@RequestScoped // JSF-managed scope.
public class GoodBean {

    @ManagedProperty("#{springBeanName}")
    private SpringBeanClass springBeanName; // Setter required.
}
Run Code Online (Sandbox Code Playgroud)
@Component // Spring-managed.
@Scope("request") // Spring-managed scope.
public class GoodBean {

    @Autowired
    private SpringBeanClass springBeanName; // No setter required.
}
Run Code Online (Sandbox Code Playgroud)

请注意,当您按照javadocSpringBeanFacesELResolver注册时,faces-config.xml

<application>
    ...
    <el-resolver>org.springframework.web.jsf.el.SpringBeanFacesELResolver</el-resolver>
</application>
Run Code Online (Sandbox Code Playgroud)

因此你可以在EL中引用Spring托管bean #{springBeanName},然后你也可以引用它们@ManagedProperty,因为它基本上设置了给定EL表达式的评估结果.反过来说,通过注入JSF托管bean @Autowired是不受支持的.但是@Autowired,当您在Spring自动上传的上下文中手动注册JSF托管bean实例时,可以在JSF托管bean中使用.另请参见如何很好地集成JSF 2和Spring 3(或Spring 4).

@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
public class GoodBean extends SpringBeanAutowiringSupport implements Serializable {

    @Autowired
    private SpringBeanClass springBeanName; // No setter required.

    @PostConstruct
    private void init() {
        // springBeanName is now available.
    }
}
Run Code Online (Sandbox Code Playgroud)

SpringBeanAutowiringSupport VS @Autowired

Spring @PostConstruct对JSF范围的支持有限.没有JSF的等价物@XxxScoped.您基本上要么自己创建自己的作用域,要么坚持在Spring自动化上下文中手动注册JSF托管bean实例,如上所示.

而且,从另一方面来看,Spring WebFlow通过新的@Scope注释在JSF 2.2中被接管.因此,如果您刚好使用JSF 2.2,那么如果您只想要流量范围,则不一定需要使用Spring WebFlow.


CDI - 试图统一这一切

自Java EE 6以来,CDI作为Spring DI的标准替代品提供.它分别具有注释@Scope@ViewScoped注释以及它自己的一组范围.我不确定它是如何与Spring交互的,因为我不使用Spring,但是@FlowScoped在一个内部工作@Named,并且@Inject在一个内部@Inject可以引用一个@ManagedBeanbean.另一方面,@ManagedProperty@ManagedBeanbean 内部不起作用.

CDI的目的是将所有不同的bean管理框架统一到一个规范/接口中.Spring可能是一个完整的CDI实现,但他们选择只部分实现它(只@Named支持JSR-330 ,但@ManagedProperty不支持JSR-299 ).另见Spring会支持CDI吗?本教程.

JSF将转向CDI进行bean管理,@Named并在未来版本中弃用和朋友.

也可以看看:


tyl*_*den 7

还有另一种方法可以通过简单地扩展JSF bean来在JSF管理的bean中使用Spring管理的bean SpringBeanAutowiringSupport,Spring将处理依赖注入.

@ManagedBean // JSF-managed.
@ViewScoped // JSF-managed scope.
public class GoodBean extends SpringBeanAutowiringSupport {

    @Autowired
    private SpringBeanClass springBeanName; // No setter required.

    // springBeanName is now available.
}
Run Code Online (Sandbox Code Playgroud)

  • 您是最初问这个问题的人吗?在JSF中,使用@ManagedBean批注是** DEPRECATED **,与JSF定义的范围一样。一切都将成为CDI,并且由于Spring也对这些cdi注释也“了解”(如果我正确阅读了所有内容),因此选择这些“新” CDI注释是更好的方法。无需扩展课程等。我几乎倾向于拒绝投票,但应由真正的专家决定) (2认同)