Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SpringJSF集成:如何在JSF托管bean中注入Spring组件/服务?_Spring_Jsf_Dependency Injection_Integration_Managed Bean - Fatal编程技术网

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

SpringJSF集成:如何在JSF托管bean中注入Spring组件/服务?,spring,jsf,dependency-injection,integration,managed-bean,Spring,Jsf,Dependency Injection,Integration,Managed Bean,我知道托管bean的工作方式类似于控制器,因为您唯一的任务是将视图层与模型“链接” 要将bean用作托管bean,我必须声明@ManagedBean注释,这样我就可以直接将JSF与bean通信 如果我想在这个managedBean中注入一些组件(来自Spring),我有两种可能的方法: 选择ManagedBean中的属性(如“BasicDAO”)并在属性上方声明@ManagedProperty(#{“BasicDAO”})。为此,我在ManagedBean中注入了Spring中的bean“bas

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

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

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

  • 选择ManagedBean中的属性(如“BasicDAO”)并在属性上方声明
    @ManagedProperty(#{“BasicDAO”})
    。为此,我在ManagedBean中注入了Spring中的bean
    “basicDAO”

  • 在ManagedBean类中声明@Controller,然后我将有
    @ManagedBean
    @Controller
    注释,所有注释都在一起。在属性
    “BasicDAO”
    中,我必须使用Spring的
    @Autowired

  • 我的理解正确吗?

    @ManagedBean
    vs
    @Controller
    首先,您应该选择one框架来管理bean。您应该选择JSF或Spring(或CDI)来管理bean。虽然以下方法可行,但它从根本上是错误的:

    @ManagedBean // JSF-managed.
    @Controller // Spring-managed.
    public class BadBean {}
    
    最后,您将得到同一托管bean类的两个完全独立的实例,一个由JSF管理,另一个由Spring管理。当您将EL引用为
    {someBean}
    时,并不直接清楚在EL中实际使用的是哪一个。如果您在
    faces config.xml
    中注册了,那么它将是Spring管理的,而不是JSF管理的。如果没有,那么它将是JSF管理的

    另外,当您从
    javax.faces.*
    包中声明JSF托管bean特定的作用域时,例如
    @RequestScoped
    @ViewScoped
    @SessionScoped
    @ApplicationScoped
    ,它将只被
    @ManagedBean
    识别和使用。它不会被
    @Controller
    理解,因为它需要自己的
    @Scope
    注释。如果不存在,则默认为singleton(应用程序范围)

    @ManagedBean // JSF-managed.
    @ViewScoped // JSF-managed scope.
    @Controller // Spring-managed (without own scope, so actually becomes a singleton).
    public class BadBean {}
    
    当您通过
    {someBean}
    引用上述bean时,它将返回Spring管理的应用程序范围bean,而不是JSF管理的视图范围bean


    @ManagedProperty
    vs
    @Autowired
    特定于JSF的
    @ManagedProperty
    仅在JSF托管bean中有效,即当您使用
    @ManagedBean
    时。特定于Spring的
    @Autowired
    仅在Spring管理的bean中工作,即当您使用
    @Controller
    时。以下方法的等效性较小或较大,不能混合使用:

    @ManagedBean // JSF-managed.
    @RequestScoped // JSF-managed scope.
    public class GoodBean {
    
        @ManagedProperty("#{springBeanName}")
        private SpringBeanClass springBeanName; // Setter required.
    }
    
    请注意,当您按照

    或者,当您的体系结构不允许从不同的基类扩展bean时,您可以始终在Spring Autowiable上下文中手动注册JSF托管bean实例,如下所示。有关技巧,请参见

    @ManagedBean // JSF-managed.
    @ViewScoped // JSF-managed scope.
    public class GoodBean implements Serializable {
    
        @Autowired
        private SpringBeanClass springBeanName; // No setter required.
    
        @PostConstruct
        private void init() {
            FacesContextUtils
                .getRequiredWebApplicationContext(FacesContext.getCurrentInstance())
                .getAutowireCapableBeanFactory().autowireBean(this);
    
            // springBeanName is now available.
        }
    }
    

    @XxxScoped
    vs
    @Scope
    Spring的
    @Scope
    对JSF作用域的支持有限。JSF的
    @ViewScoped
    没有等价物。基本上,您要么自行扩展自己的作用域,要么坚持在Spring Autowiable上下文中手动注册JSF托管bean实例,如上所示

    另一方面,SpringWebFlow在JSF2.2中通过新的
    @FlowScoped
    注释被接管。因此,如果您碰巧已经使用了JSF2.2,那么如果您只想使用流范围,就不一定需要使用SpringWebFlow


    CDI-试图将其统一起来 自JavaEE6以来,CDI作为SpringDI的标准替代品提供。它分别有
    @命名的
    @注入的
    注释以及自己的作用域集。我不确定它是如何与Spring交互的,因为我没有使用Spring,但是
    @Inject
    @ManagedBean
    中工作,而
    @ManagedBean
    中的
    @ManagedProperty
    可以引用
    @命名的
    bean。另一方面,
    @ManagedProperty
    在名为
    @的
    bean中不起作用

    CDI的目的是将所有不同的bean管理框架统一到一个规范/接口中。Spring本可以是一个完整的CDI实现,但他们选择只部分实现它(只支持JSR-330
    javax.inject.
    ,但不支持JSR-299
    javax.enterprise.context.
    )。另见和

    JSF将转向CDI进行bean管理,并在将来的版本中弃用
    @ManagedBean
    和friends

    @Named // CDI-managed.
    @ViewScoped // CDI-managed scope.
    public class BetterBean implements Serializable {
    
        @Inject
        private SpringBeanClass springBeanName; // No setter required.
    
        @PostConstruct
        private void init() {
            // springBeanName is now available.
        }
    }
    
    另见:

      • 实现这一点的简单方法是通过XML。我在已经制作好的jsf托管bean中使用了
        @Component
        ,但是
        @Autowired
        不起作用,因为托管bean已经存在于faces-config.xml中。如果必须在xml文件中保留该托管bean定义及其托管属性,则建议在托管bean标记中添加Springbean作为另一个托管属性。这里Springbean在spring config.xml中定义(可以在其他地方自动连接)。请参阅


        由我编辑。我建议要么通过注释@Managed和@Component来实现它,要么通过xml来实现两者。

        在JSF托管bean中使用Spring托管bean还有另一种方法,只需从
        SpringBeanAutowiringSupport
        扩展JSF bean,Spring就会处理依赖注入

        @ManagedBean // JSF-managed.
        @ViewScoped // JSF-managed scope.
        public class GoodBean extends SpringBeanAutowiringSupport {
        
            @Autowired
            private SpringBeanClass springBeanName; // No setter required.
        
            // springBeanName is now available.
        }
        

        您说过:“特定于JSF的@ManagedProperty只在JSF托管bean中起作用,即当您使用@ManagedBean时”。但是我使用@ManagedProperty引用了一个Springbean,这很好用。我是怎么说的:我正在使用@ManagedProperty(#{'basicDAO'),bean'basicDAO'是@Repository bean。@ManagedProperty是集成sp的方法(我遇到过)
        @ManagedBean // JSF-managed.
        @ViewScoped // JSF-managed scope.
        public class GoodBean implements Serializable {
        
            @Autowired
            private SpringBeanClass springBeanName; // No setter required.
        
            @PostConstruct
            private void init() {
                FacesContextUtils
                    .getRequiredWebApplicationContext(FacesContext.getCurrentInstance())
                    .getAutowireCapableBeanFactory().autowireBean(this);
        
                // springBeanName is now available.
            }
        }
        
        @Named // CDI-managed.
        @ViewScoped // CDI-managed scope.
        public class BetterBean implements Serializable {
        
            @Inject
            private SpringBeanClass springBeanName; // No setter required.
        
            @PostConstruct
            private void init() {
                // springBeanName is now available.
            }
        }
        
        @ManagedBean // JSF-managed.
        @ViewScoped // JSF-managed scope.
        public class GoodBean extends SpringBeanAutowiringSupport {
        
            @Autowired
            private SpringBeanClass springBeanName; // No setter required.
        
            // springBeanName is now available.
        }