5

我正在尝试使用 spring 为 jsf 提供托管 bean。我假设 @ManagedBean 将被 JSF 容器拾取以将 JSF 中的 EL 链接到托管 bean,即使我通过在 faces-config.xml 中配置 spring 使用来使用 spring。

Spring 将提供 bean,但现在谁来管理 bean 的范围?

我尝试在 bean 上进行注释以使其成为请求范围,但它们不起作用。

@ManagedBean(name="helloBean") //meant for JSF
@RequestScoped //meant for JSF
@Scope(value="request") //meant for spring
@Controller //meant for spring
public class HelloBean implements Serializable {

实际上早些时候我使用的是普通的 JSF,@ManagedBean 和 @RequestScoped 运行良好。现在,当我尝试使用 spring 进行集成时,范围不起作用。

我什至尝试在 spring 配置中设置 bean 范围,但它们在 spring 上下文(单例和原型)中按预期工作,但不是 web 请求上下文。

我试图避免使用上面的 @Scope 和 @Controller 注释,希望 JSF 将管理范围,但看起来不像。

下面是我的 spring config 和 MyHelloBean 的文件片段,它可能有助于更好地沟通。

<bean id="helloBean" class="com.mkyong.common.HelloBean" init-method="init" />

<bean id="myHelloBean" class="com.mkyong.common.MyHelloBean" init-method="init" >
        <property name="helloBean" ref="helloBean"></property>
</bean>

@ManagedBean
@RequestScoped
@Scope(value="request")
@Controller
public class MyHelloBean implements Serializable {

    private static final long serialVersionUID = 1L;
    //@ManagedProperty(value = "#{helloBean}")
    private HelloBean helloBean;

见上面的 MyHelloBean 我正在使用 spring DI 来设置由 spring 设置的 helloBean。我已经注释掉了@ManagedBean,我想我可以把它留在那里,因为它会被spring以任何方式忽略,我猜JSF不会处理它,但为了安全起见,我把它注释掉了,让JSF不处理它。

为了完成我在 faces-config 中使用下面来激活 spring 使用。

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

问候,

米腾。

4

2 回答 2

5

我们的团队在集成 JSF 和 Spring bean 时遇到了类似的问题,包括它们的作用域问题。我在这里分享我们的知识。

范围

基本上现在,当您在应用程序上下文中定义时,Spring 将管理您的 bean,从而管理范围。Spring 会将 JSF 范围注释映射到他的本机范围注释。

  • Spring 和 JSF 支持都提供范围的示例:

@RequestScoped 注解将映射到 @Scope("request") Spring 的注解等,以及其他支持的范围。

  • 当 Spring 不支持 JSF 提供的范围时的示例:

@ViewScoped 未在 Spring 的本机范围注释中定义,因此(不确定)它将使用 Spring 的默认范围,即单例或请求范围(不确定)。

豆类注射液

在 JSF2 中,您使用 @ManagedProperty 注释进行注入,而 Spring 使用 @Autowired 注释。有什么区别和选择哪个?

  • 使用 @ManagedProperty 注入 Spring bean:

您希望注入的 Spring 组件必须具有一个与 jsf 注入注释的值匹配的值:@Component(value = "valueMatches") 注入 @ManagedProperty(value = "valueMatches")。

  • 使用 @Autowired 注入 Spring bean:

您希望注入的 Spring 组件必须不需要自定义值来区分,如果它是您要注入的 bean 的唯一实现:@Component 注入 @Autowired。

我们的方式

我们使用 Spring 的注解来定义 Beans、Scopes 和 Injection。

我们用@Scope(value = "desiredScope")、@Controller(value = "beanName") 和@Qualifier(value = "beanName") 注释标记了JSF bean。稍后可以在 faces-config.xml 中通过 @Controller 注释中定义的“beanName”值从 JSF 上下文中访问它。

我们用 @Service 注解标记了 Spring 服务。

我们使用 @Autowired 注解注入 Spring 服务和 JSF bean。

我们在 Web 上找到了 ViewScope 和 FlashScope 自定义实现,并将它们用于我们的 bean。因此,我们没有丢失任何 JSF2 作用域,甚至添加了新作用域。

希望这可以帮助。

于 2012-05-31T08:52:00.557 回答
2

您的方法有点令人困惑,因为您似乎正在混合 Spring XML 配置和基于 Spring Annotation 的配置。如这里所描述的示例,如果您使用带注释的配置,那么您应该:

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

订购 Spring 扫描注释。否则,如果您使用的是 XML 配置,那么您应该:

<bean id="helloBean" class="com.mkyong.common.HelloBean" init-method="init" scope="request" />

默认情况下,scope对于 Spring bean 是singleton.

于 2012-05-31T07:48:57.407 回答